Проблема вызова функции, которая использует strtok () внутри цикла while - PullRequest
1 голос
/ 27 января 2020

Привет, я изо всех сил пытаюсь понять, что не так с моей программой. Мое лучшее предположение, что-то связанное с этой строкой кода здесь:

scanf("%s", str);

Дело в том, что я пытаюсь вызвать функцию, которая использует strtok для строки, переданной ей, набранной пользователем, все в течение некоторого времени l oop, как показано в примере кода ниже:

int i = 0;
char str[80];
while(i != 3){
    printf("Type in some string so i can break it: ");
    scanf("%s", str);
    testFunc(str);
    printf("Loop %i ended.\n", i);
    i++;
}
return 1;

Результат (не то, что я хочу, смотрите ниже, что я на самом деле хочу):

Type in some string so i can break it: hey there how are you doing!
hey
Loop 0 ended.
Type in some string so i can break it: 
there
Loop 1 ended.
Type in some string so i can break it: 
how
Loop 2 ended.

Причина, по которой я думаю, что это вызвано строкой scanf, заключается в том, что программа работает нормально, когда вместо нее используется какая-то фиктивная предварительно объявленная строка

int i = 0;
while(i != 3){
    char str[80] = "hey there how are you doing!";
    testFunc(str);
    printf("Loop %i ended.\n", i);
    i++;
}
return 1;

Результат:

hey
there
how
are
you
doing!
Loop 0 ended.
hey
there
how
are
you
doing!
Loop 1 ended.
hey
there
how
are
you
doing!
Loop 2 ended.

Вот функция, которая использует strtok, большая часть кода взята из https://www.tutorialspoint.com/c_standard_library/c_function_strtok.htm

int testFunc(char linha[80]){
    //
   const char s[2] = " ";
   char *token;

   /* get the first token */
   token = strtok(linha, s);

   /* walk through other tokens */
   while(token != NULL) {
      printf("%s\n", token);

      token = strtok(NULL, s);
   }
   return 1;
}

Я озадачен, похоже, что программа выполняет testFun c () параллельно с основной функцией.

Ответы [ 2 ]

1 голос
/ 27 января 2020

Я думаю, проблема в том, что когда вы выполняете это l oop:

while(i != 3){
    printf("Type in some string so i can break it: ");
    scanf("%s", str);
    testFunc(str);
    printf("Loop %i ended.\n", i);
    i++;
}

scanf получает только одно слово за раз, поэтому l oop циклически повторяется 3 раза, вы получаете только 3 слова независимо от длины входной строки.

С другой стороны, в другом примере у вас уже есть строка, которую нужно разбить на части, чтобы функция работала.

Существуют различные способы чтобы получить разнесенные строки из консоли, но вот что я считаю хорошим вариантом для этого:

str[MAX_SIZE];
fgets(str, MAX_SIZE, stdin); 
// where MAX_SIZE is the maximum size you want to allow for the string, 
//must be smaller than str.
0 голосов
/ 27 января 2020

Согласно scanf (3) справочная страница:

Соответствует последовательности символов, не являющихся пробелами; следующий указатель должен быть указателем на начальный элемент массива символов, который достаточно длинный, чтобы содержать входную последовательность и завершающий нулевой байт ('\ 0'), который добавляется автоматически. Строка ввода останавливается на пустом месте или на максимальной ширине поля, в зависимости от того, что произойдет раньше

Для ввода можно использовать fgets или fread:

/* fread (enter EOF (ctrl-d) to stop) */
int nread = 0;
char buffer[1000];
while (!feof (stdin))
  fread (buffer, 1, 999, stdin);
buffer[nread] = '\0'; /* nul-terminated. */

/* or fgets (reads a line of text with trailing newline */
fgets (buffer, 999, stdin);
...