2016-05-17 4 views
0

Я пытаюсь отсканировать строку из файла, используя следующий код. Но моя программа печатает странные символы. Любые идеи, как остановить это и как сохранить пробелы между словами при печати строки?Сканирование из файла в C

вот содержимое файла (test.txt)  (test.txt)

Вот результат моей программы:

output

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

typedef struct 
{ 
    char word[80]; 
    int length; 
    int freq; 
} sent; 

int main() 
{ 
    sent a[50]; 
    int v,status; 
    int i=0,cnt=0; 
    char*y; 

    FILE*p; 
    p=fopen("C:\\Users\\User\\Desktop\\test.txt","r"); 
    status=fscanf(p,"%s",a[i].word); 
    while(status !=EOF){ 
     i++; 
     status=fscanf(p,"%s",a[i].word); 
    } 
    for(i=0;i<50;i++) 
    { 
     char *y=strtok(a[i].word,"[email protected]#$%&*?."); 

     while(y!=NULL) 
     { 
     printf("%s",y); 
     y=strtok(NULL,"[email protected]#$%&*?."); 

     } 
    } 
} 
+6

Пожалуйста отправьте содержимое test.txt. Я предполагаю, что у вас нет 50 слов в файле. –

+0

fscanf (p, "% s", a [i ]word); может закончиться переполнением буфера, используйте fscanf (p, «% 79s», [i] .word); или fgets(). и проверьте наличие ошибок после fopen() – 12431234123412341234123

ответ

0

Это просто строка манипуляции. Я немного отлаживал и модифицировал вашу программу, так что вместо нежелательных сообщений выводился текст. Возможно, вам придется изменить его еще немного, но теперь он печатает содержимое файла. Причина, по которой вы получили мусорный характер, состоит в том, что цикл не знает, когда остановиться, когда строка не завершена, поэтому вы получаете содержимое памяти из чего-то другого. Рекомендуемый способ: fgets для чтения файла, а пробел сохраняется.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

typedef struct { 
    char *word; 
    int length; 
    int freq; 
} sent; 

int words(const char *sentence) { 
    int count, i, len; 
    char lastC; 
    len = strlen(sentence); 
    if (len > 0) { 
     lastC = sentence[0]; 
    } 
    for (i = 0; i <= len; i++) { 
     if (sentence[i] == ' ' && lastC != ' ') { 
      count++; 
     } 
     lastC = sentence[i]; 
    } 
    if (count > 0 && sentence[i] != ' ') { 
     count++; 
    } 
    return count; 
} 

int main() { 
    sent a[50]; 
    int v, status; 
    int i = 0, cnt = 0; 
    FILE *p; 
    p = fopen("data.txt", "r"); 
    char buf[100], title[100]; 
    fgets(buf, sizeof buf, p); 
    int j = words(buf); 
    char *yy; 
    yy = strtok(buf, "[email protected]#$&*?%."); 

    while (yy != NULL) { 
     a[i].word = yy; 
     yy = strtok(NULL, "[email protected]#$&*?%."); 
     i++; 
    } 

    for (int k = 0; k<i; k++) { 
     printf("%s", a[k].word); 
    } 
} 

Программа выполняет токенизацию буфера и сохраняет пробелы. Я изменил способ чтения файла на fgets.

data.txt

По шкале от одного до десяти, что $ Ваш любимый цвет алфавита

выход

По шкале от одного до 10 Ваш любимый цвет алфавита

+2

Просьба описать, какие изменения вы должны внести в код OP, чтобы он работал на вас. –

+0

@RSahu Я добавил улучшенный код и более подробное описание. Надеюсь, вы снова одобрите или прокомментируете. –

+0

@ Programmer400 - вы не упоминаете, почему ваш код лучше или почему его код не удалось .... – Soren

2

Как люди отмечают, вы, вероятно, не имея 50 слов в файле вы читаете, но ваш цикл пытается перебрать 50 в любом случае ...., поэтому эта линия

for(i=0;i<50;i++) 

должен быть изменен, чтобы

int w; 
for(w=0;w<i;w++) 

и вы должны заменить использование iw внутри цикла (или, возможно, вы использовали переменную cnt внутри цикла while, так как это в настоящее время не используется в вашем коде).

И вам нужна защита для переполнения буфера, которая произошла, если ваш файл будет содержать более 50 слов и т. Д., Но это выходит за рамки этого ответа.

Update, чтобы ответить на ваш комментарий:

Чтобы иметь пространство между словами, вы просто просто добавить их к выходу, как

printf("%s ",y); 

Ваш зсапЕ будет, однако, прекратить сканстроку в любой space (пробел 20), новая строка (\ n), вкладка (\ t) или return (\ r) будут завершающими символами для ваших строк. Если вы хотите сохранить и вывести то же самое, вы просто просто сканируете для таких же, как

char theString[50]; 
    char theSpace; 
    int matched = scanf("%s%c",theString, theSpace); 

и если соответствует == 2, то вы просканировали как строку и пространство, которое прекращается сканирование, и вы можете распечатать его, как

printf("%s%c",theModifiedString,theSpace); 
+0

поэтому 'i' здесь ссылается на количество слов, а не количество символов в файле ..... я подсчитал слова в файле и изменил цикл в соответствии с номером ... он работал, но нет пробелов между словами, как я могу сохранить промежутки между ними ?? .... спасибо за ответ, который он помог –

+0

См. обновленный ответ – Soren

+0

, если я использовал 'printf ("% s ", y);' он не будет работать, потому что У меня есть специальные символы между символами самого слова, поэтому между символами в слове будут пробелы. –

 Смежные вопросы

  • Нет связанных вопросов^_^