0

快速提问,我在这里做错了什么。此代码的目的是将输入转换为字符串,输入为“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'; 
}
4

2 回答 2

4

你的程序有几个问题:

  • 您在 exprtemp数组中使用相同的索引。这是第一次工作,因为两者都将从0 开始,但是当您想要处理2nd数字时,您需要将temp数组中的索引重置回0. 显然,这不能使用单个索引来完成。您必须使用两个索引,i并且j.
  • 当您完成对第二个数字(34in "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

您的方法非常脆弱……如果用户在输入数字之间给出多个空格……您的程序将失败。

于 2010-03-08T09:29:22.023 回答
0

主要问题是copyTemp写入temp[i],但每次调用都copyTemp初始化iindex_counter,而不是 0。这意味着每次调用都copyTemp追加到现有temp缓冲区而不是覆盖旧内容,sscanf因此总是重新读取相同的字符串。您需要使用单独的索引来跟踪从输入缓冲区读取的位置以及写入输出缓冲区的位置。

其他问题: * 永远不要** 使用ggets. 曾经。改为使用fgets。* 您在copyTemp. 你可以这样做:

if (expr[i] == '0' || expr[i] == '1' || ...)

或更好:

if (isdigit(expr[i]))
  • copyTemp应采取一些预防措施,以免其目标缓冲区溢出。(请注意,copyTemp甚至不需要将目标缓冲区作为参数。)

  • 您应该避免使用全局变量。最好copyTemp使用一个参数来指定从输入字符串开始读取的位置以及它是否返回了它停止的索引。

于 2010-03-08T09:30:38.290 回答