【问题标题】:Segmentation error while working with strings使用字符串时出现分段错误
【发布时间】:2020-11-27 15:35:17
【问题描述】:

给定一个字符串,num,由字母和数字组成,求给定字符串中每个数字(0-9)出现的频率。

'''

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include<ctype.h>

int main() {

    /* Enter your code here. Read input from STDIN. Print output to STDOUT */ 
    char num[20];
    int i;
    int count[15]={0};
  
    scanf("%s",num);
    

    for(i=0;i<10;i++){
        printf("\n");     
        for(int j=0;j<strlen(num);j++){
            if(isdigit(num[j])){
               if(i == num[j]-'0'){
                count[i]+=1;
            }

            }
           
        }
        printf("\nCount %d:%d",i,count[i]);
    }  

    for(i=0;i<10;i++){
        printf("%d ",count[i]);
    } 
    return 0;
}

'''

输出:

计数 0:5

计数 1:9

计数 2:5

计数 3:12

计数 4:8

计数 5:11

计数 6:15

计数 7:4

计数 8:4

退出,分段错误

为什么检查数字是否为9时不起作用?

【问题讨论】:

  • char num[20]; 为 19 个字符加上一个空终止符分配空间,但打印的计数显示 73 位。无论您输入什么输入都会超出缓冲区。
  • 此外,因为您在一行之前打印\n 字符,而不是在设计的末尾,所以计数为 9 的行保留在缓冲区中,而不是立即打印。该程序实际上完成了这些初始循环并继续执行进一步的代码,由于缓冲区溢出而崩溃。
  • @EricPostpischil 啊,我完全忘记了字符串的大小。非常感谢!

标签: c string segmentation-fault


【解决方案1】:

查看您的输出时,您输入的字符串似乎比 19 个字符长得多。所以你的程序有未定义的行为。

这个

scanf("%s",num);

是你永远不应该做的事情。请记住将输入限制为缓冲区的大小。那就是:

char num[20];     // Size of buffer is 20

scanf("%19s",num);
        ^^
        At max allow 19 characters so that there is also room for the string termination

或者——也许更好——使用fgets而不是scanf。 fgets 的一个好处是它将缓冲区大小作为参数 - 因此您永远不会忘记指定它。

还要注意,您的外部 for 循环是不必要的。您可以使用单个循环直接更新数组。

// for(i=0;i<10;i++){  Delete this - it's not needed

    for(int j=0;j<strlen(num);j++)
    {
        if(isdigit(num[j]))
        {
            count[num[j]-'0']+=1;  // Update array
        }
    }

顺便说一句:计数器中只需要 10 个元素,即

int count[15]={0};   --->  int count[10]={0};

【讨论】:

  • 我还建议使用fgets(buffer, BUFSIZE, stdin) 而不是scanf
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-16
相关资源
最近更新 更多