快速提问,我在这里做错了什么。此代码的目的是将输入转换为字符串,输入为“12 34”,在“12”和“32”之间有一个空格,并从一个整数变量转换并打印两个单独的数字数。为什么第二次调用函数copyTemp不会产生值34?我有一个index_counter变量跟踪字符串索引,它意味着跳过'空格'字符?我做错了什么?
感谢。
#include <stdio.h>
#include <string.h>
int index_counter = 0;
int number;
void copyTemp(char *expr,char *temp);
int main(){
char exprstn[80]; //as global?
char tempstr[80];
gets(exprstn);
copyTemp(exprstn,tempstr);
printf("Expression: %s\n",exprstn);
printf("Temporary: %s\n",tempstr);
printf("number is: %d\n",number);
copyTemp(exprstn,tempstr); //second call produces same output shouldnt it now produce 34 in the variable number?
printf("Expression: %s\n",exprstn);
printf("Temporary: %s\n",tempstr);
printf("number is: %d\n",number);
return 0;
}
void copyTemp(char *expr,char *temp){
int i;
for(i = index_counter; expr[i] != '\0'; i++){
if (expr[i] == '0'){
temp[i] = expr[i];
}
if (expr[i] == '1'){
temp[i] = expr[i];
}
if (expr[i] == '2'){
temp[i] = expr[i];
}
if (expr[i] == '3'){
temp[i] = expr[i];
}
if (expr[i] == '4'){
temp[i] = expr[i];
}
if (expr[i] == '5'){
temp[i] = expr[i];
}
if (expr[i] == '6'){
temp[i] = expr[i];
}
if (expr[i] == '7'){
temp[i] = expr[i];
}
if (expr[i] == '8'){
temp[i] = expr[i];
}
if (expr[i] == '9'){
temp[i] = expr[i];
}
if (expr[i] == ' '){
temp[i] = '\0';
sscanf(temp,"%d",&number);
index_counter = i+1; //skips?
}
}
// is this included here? temp[i] = '\0';
}
答案 0 :(得分:4)
您的计划中存在一些问题:
expr
和temp
数组。这适用于
这两次都是第一次0
开始但是当你想要
处理2nd
号码,您需要
将索引重置为temp
数组
回到0
。显然这不可能
使用单个索引完成。你会
必须使用两个索引,i
和j
。34
in
"12 34"
)你将达到结束
字符串,因此sscanf
永远不会
第二次运行(在
一般的最后一次)。所以
在for循环之后你需要另一个
sscanf提取最后一个数字。此外,一旦从字符串中提取数字并递增i,您应该从函数返回。 gets
()并使用
fgets
()而不是因为安全
的原因。像这样。
void copyTemp(char *expr,char *temp){
int i;
int j = 0;
for(i = index_counter; expr[i] != '\0'; i++){
if (expr[i] >= '0' && expr[i]<='9'){
temp[j++] = expr[i]; // copy the digit into temp..increment j.
}
else if (expr[i] == ' '){ // space found..time to extract number.
temp[j] = '\0'; // terminate the temp.
sscanf(temp,"%d",&number); // extract.
index_counter = i+1; // skip the space.
return; // done converting...return..must not continue.
}
}
// have reached the end of the input string..and still need to extract a
// the last number from temp string.
temp[j] = '\0';
sscanf(temp,"%d",&number);
}
在这些更改之后,它按预期工作:
$ gcc b.c 2> /dev/null && ./a.out
12 34
Expression: 12 34
Temporary: 12
number is: 12
Expression: 12 34
Temporary: 34
number is: 34
你的方法非常脆弱......如果用户在输入数字之间给出多个空格......你的程序就会失败。
答案 1 :(得分:0)
主要问题是copyTemp
写入temp[i]
,但每次调用copyTemp
都会将i
初始化为index_counter
,而不是0。这意味着每次调用copyTemp
都会附加到现有的temp
缓冲区而不是覆盖旧内容,因此sscanf
会重新读取相同的字符串。您需要使用单独的索引来跟踪从输入缓冲区读取的位置以及写入输出缓冲区的位置。
其他问题:
*永远不要**使用ggets
。 自从。请改用fgets
。
*您在copyTemp
中复制了大量代码。你可以这样做:
if (expr[i] == '0' || expr[i] == '1' || ...)
或更好:
if (isdigit(expr[i]))
copyTemp
应该采取一些预防措施,不要溢出目标缓冲区。 (请注意,copyTemp
甚至不需要将目标缓冲区作为参数。)
您应该避免使用全局变量。 copyTemp
最好采用一个参数来指定从输入字符串开始读取的位置,以及它是否从它停止的位置返回索引。