我已经有几年没有编程了,我有一个问题sscanf
:
我想使用sscanf
将一个字符串分成几个,但sscanf
在一个循环中给了我分割错误。为什么?如何在一个周期中使用sscanf
而不会发生?
例:
int main() {
char str[100];
char mat[100][100]; int i = 0;
strcpy(str, "higuysnilovestackoverflown2234nhaha");
while (sscanf(str, "%s", mat[i]) == 1) i++;
}
int sscanf(const char *str, const char *format, ...);
while(sscanf(str,"%s", mat[i]) == 1) i++;
由于str
在原型中是常数,因此无法通过sscanf
更改(除非sscanf
非常损坏:)),因此它成功地一遍又一遍地重复,一直返回 1... 因此,i
会增加,并且在某些时候您遇到了内存边界,并且系统会停止有害程序。
如果要读取多行字符串,请使用带有strtok
的循环,例如,它将遍历字符串和屈服行。
注意:我之前的回答正确地假设了之前版本的问题有一个错别字,中间有一个额外的;
while(sscanf(str,"%s", mat[i]) == 1); i++;
始终成功,因为str
是输入并且不会更改(与使用fscanf
或fgets
从文件读取不同)。
所以在这种情况下,这只是一个无限循环。
sscanf
停止在n
,将单词higuys
存储到数组mat[i]
中并返回1
。循环条件为 true,i
递增,并且该过程继续作为具有相同源字符串的mat
的下一个元素作为目标......mat
的每个元素都接收相同的higuys
字符串,循环继续,导致缓冲区溢出,调用未定义的行为并最终崩溃。
以下是修改代码以使其工作的方法:
#include <stdio.h>
int main(void) {
const char *str = "higuysnilovestackoverflown2234nhaha";
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] = %sn", j, mat[j]);
}
return 0;
}