sscanf循环仅读取第一个输入多次

时间:2018-12-17 14:52:44

标签: c string while-loop segmentation-fault scanf

我使用sscanf分割了一个从输入中提取的字符串,并将每个令牌存储在结构中。问题在于sscanf仅读取字符串的第一个单词,而不会前进到下一个单词,一遍又一遍地打印相同的标记。这是代码。

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

#define dim 30

typedef struct string { 
  char* token[dim];
}string;

int main() {
  string* New = (string *)malloc(dim*sizeof(string));
  char* s;
  char buffer[dim];
  int i = 0, r = 0, j = 0;
  s = (char*)malloc(sizeof(char*));
  printf("\nString to read:\n");
  fgets(s, dim, stdin);
  printf("\nThe string is: %s", s); 
  while(sscanf(s, " %s ", buffer) != EOF) {
    New->token[i] = malloc(dim*sizeof(char));
    strcpy(New->token[i], buffer);
    printf("\nAdded: %s", New->token[i]);
    ++i;
  }
}

例如,如果我输入“ this is a string”作为输入,则sscanf将多次获得“ this”一词,而不会继续输入下一个单词。

1 个答案:

答案 0 :(得分:2)

您需要增加源sscanf()读取的指针,以免一次又一次从同一点读取。

此外,您为s动态分配的内存没有任何意义。无论如何都太少了。通过稍后在代码中对fgets()的调用,我可以看到您是要说s = malloc(dim * sizeof(char));的,所以我继续并解决了这个问题。

示例:

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

#define dim 30

typedef struct string {
  char* token[dim];
} string;

int main() {
  string* New = malloc(dim*sizeof(string));
  char* s;
  char buffer[dim];
  int i = 0;
  s = malloc(dim * sizeof(char));
  fgets(s, dim, stdin);
  printf("The string is: %s\n", s); 
  char* ptr = s;
  int offset;
  while (sscanf(ptr, "%s%n", buffer, &offset) == 1) {
    ptr += offset;
    New->token[i] = malloc(strlen(buffer) + 1);
    strcpy(New->token[i], buffer);
    printf("Added: %s\n", New->token[i]);
    ++i;
  }

  // do work

  for(int j = 0; j < i; ++j)
    free(New->token[i]);
  free(New);
  free(s);

  return 0;
}

输出:

The string is: this is a string
Added: this
Added: is
Added: a
Added: string

PS:我不确定您所想到的结构的架构,也许您需要花一两分钟,三思而后行。我的意思是您的设计方法是否有意义。

PPS:与您的问题无关:Do I cast the result of malloc?不!

编辑:正如@chux所说," "的{​​{1}}中的" %s%n"毫无用处。我将其更改为sscanf()

此外,为了精确地保留所需的内存(在处理动态内存分配时要做的事情),"%s%n"更改为New->token[i] = malloc(dim*sizeof(char));