2015-12-04 77 views
0

我正在写一个代码,它应该在字符串中找到空格,并在不同的字符串数组之前和之后分开部分。第一个问题是scanf甚至没有正确地读取我的字符串,但我也没有在C中使用字符串,并且好奇它是否正确(特别是使用[]数组)。Scanf在C中没有正确读取字符串。怎么了?

char expr[50]; 
char *a[50]; 
scanf("%s",expr); 
int i=0; 
int j=0; 

while (strlen(expr)!=0){ 
    if (expr[i]==' '){ 
     strncpy(a[j],expr,i); 
     strcpy(expr,expr+i+1); 
     j++; 
     i=0; 
    } 
    else { 
     if (strlen(expr)==1){ 
      strcpy(a[j],expr); 
      strcpy(expr,""); 
      j++; 
      i=0; 
     } 
     else i++; 
    } 

} 

i=0; 

for (i=0; i<j; i++){ 
    printf("%s\n",a[i]); 
} 
return 0; 
+2

scanf的默认停止替换它。在你的情况下,它将读取所有字符,直到第一个空格字符被放入expr中,所以如果你的输入是英文句子,它将抓住第一个单词。如果你想抓住整条线,可以看看'fgets'函数。 – Taelsin

+0

'%s'转换规范停止在第一个空白处(空白,制表符,换行符等)读取 - 它正确读取,但您的期望与其设计规范不同。或者用['fgets()'](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fgets.html)或POSIX ['getline()'](http://pubs.opengroup .org/onlinepubs/9699919799/functions/getline.html),然后使用'sscanf()'分阶段解析,或者只是接受现实,让'scanf()'给你一个单词。 –

+1

另外''strncpy(a [j],expr,i);'这是个坏消息,你不会为'a'中的字符串分配空间,这会导致'未定义行为'。 –

回答

1

此代码是错误的。首先,不要使用未初始化的a[j]

添加

if((a[j]=calloc(strlen(expr)+1,sizeof(char)))==NULL)exit(1); 

strncpy(a[j],expr,i);strcpy(a[j],expr);之前分配一些内存。

二级,strcpy(expr,expr+i+1);错误,因为strcpy()不会接受重叠区域。

最后,您应该使用scanf("%49s",expr);而不是scanf("%s",expr);来避免缓冲区溢出。

+0

所以我纠正了这些事情,并且它正确地读取了字符串,但它只经过了一次,并且错误消息是“程序接收到的信号SIGSEGV,分段错误”。 –

+0

你用什么替代'strcpy(expr,expr + i + 1);'用? – dxiv

0
  1. 不要使用scanf,使用gets()为standand输入或fgets()用于从FILE*

  2. 阅读字符串分解为用空格隔开的元素只是用strtok():

char expr[50];

gets(expr); 

char* a[50]; 
int i; 

for (i = 0; i < 50; i++) 
{ 
    a[i] = (char*)malloc(10); // replace 10 with your maximum expected token length 
} 

i = 0; 

for (char* token = strtok(expr, " "); token != NULL; token = strtok(NULL, " ")) 
{ 
    strcpy(a[i++], token); 
} 

for (int j = 0; j < i; j++) 
{ 
    printf("%s\n", a[j]); 
} 


// don't forget to free each a[i] when done. 

  • 为了简化此示例使用废弃的函数如strcpy,考虑在那些不包括在格式字符串空格与strcpy_s