我没有编程几年,我对sscanf
提出了一个问题:
我想使用sscanf
将字符串分成几个字符串,但sscanf
在一个周期中给出了分段错误。这是为什么?如何在不发生循环的情况下使用sscanf
?
示例:
int main() {
char str[100];
char mat[100][100]; int i = 0;
strcpy(str, "higuys\nilovestackoverflow\n2234\nhaha");
while (sscanf(str, "%s", mat[i]) == 1) i++;
}
答案 0 :(得分:4)
int sscanf(const char * str,const char * format,...);
while(sscanf(str,"%s", mat[i]) == 1) i++;
由于str
在原型中保持不变,因此无法更改(除非sscanf
非常损坏:) ),所以它成功地一遍又一遍地重复,一直返回1 ...
因此sscanf
会增加,并且在某些时候您会遇到内存边界,系统会停止您的有害程序。
如果你想读取一个多行字符串,例如使用一个带i
的循环,它将遍历你的字符串并产生一行。
注意:我之前的回答正确地假设前一个版本的问题有一个错字,中间有一个额外的strtok
;
总是成功,因为while(sscanf(str,"%s", mat[i]) == 1); i++;
是输入而且没有变化(与您使用str
或fscanf
从文件中读取时不同。)
在这种情况下,这只是一个无限循环。
答案 1 :(得分:0)
sscanf
在\n
停止,将单词higuys
存储到数组mat[i]
并返回1
。循环条件为真,i
递增,并且进程继续为mat
的下一个元素作为具有相同源字符串的目标... mat
的每个元素都接收相同的higuys
字符串,循环继续,导致缓冲区溢出,调用未定义的行为并最终崩溃。
以下是修改代码以使其正常工作的方法:
#include <stdio.h>
int main(void) {
const char *str = "higuys\nilovestackoverflow\n2234\nhaha";
char mat[100][100];
int i = 0, n = 0;
/* parse the multiline string */
while (sscanf(str, "%s%n", mat[i], &n) == 1) {
str += n;
i++;
}
/* output the array */
for (int j = 0; j < i; j++) {
printf("mat[%d] = %s\n", j, mat[j]);
}
return 0;
}