分段故障。将字符串转换为整数

时间:2018-10-01 20:40:12

标签: c

我在尝试将值从字符串指针数组转换为整数值时遇到问题:token [1]。但是,每当我在第一个索引中不指定整数时,都会遇到分段错误,在某些情况下,我不需要数字。例如,如果我只想键入命令:list。之后,我会遇到细分错误。如果不存在整数,如何存储将token [1]处的字符串值转换为整数?

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
int main(){
    int ch,  n = 1;
    int i = 0;
    int val = 0;
    char str[512], *token[5], *act_token;
    while(1){

            printf("Enter text: ");
            while((ch = getchar()) != '\n')
                    str[i++] = ch;
            str[i] = '\0';
            i = 0;                

            printf("string: %s\n", str);

            int spaces = 0;
            for(int counter  = 0; counter < strlen(str) + 1; counter++){
                    if(str[counter] == ' '){
                            spaces++;
                    }
            }
            printf("Spaces: %d\n", spaces); 
            strtok(str, " ");
            while(n <= spaces && (act_token = strtok(NULL, " "))){
                    token[n] = act_token;
                    n++;

            }
            token[n] = NULL;
            n = 1;
    //      printf("token[1]: %s\n", token[1]);     
            for(int x = 1; x < spaces+1; x++){
                    printf("token[%d]: %s\n", x, token[x]);

            } 

            if(isdigit(atoi(token[1])) != 0){
                    val = atoi(token[1]);
            }
            printf("value:%d\n", val);
    }

    return 0;

}

2 个答案:

答案 0 :(得分:0)

替换

        if(isdigit(atoi(token[1])) != 0){
            val = atoi(token[1]);
        }

        if(isdigit(token[1][0])) != 0){
            val = atoi(token[1]);
        }

问题是isdigit以字符作为参数。当然,手册页说它需要一个整数,但是该整数代表一个字符。

您的代码在做什么:

  1. 将令牌[1]转换为整数(如果不是有效整数,则将其转换为0)

  2. 确定该整数是否恰巧与ASCII数字匹配

  3. 如果是这样,请再次将其转换并保存值。

我怀疑那是你的意图。

我的版本检查token [1]的第一个字符是否为数字,如果是,则将其转换。确保您了解令牌[1] [0]的含义。

顺便说一句,请注意,如果您在字符串中输入5个以上以空格分隔的单词,则将存储到令牌[6]及更高的令牌中,这将产生未定义的结果(可能会崩溃)。此外,如果程序出错,用户在单词之间输入两个以上空格。

不要猜测strtok将如何检测和处理定界符。相反,让它做好自己的工作。在获取值时存储它们。为存储结果的数组选择一个极限值,然后在超出极限之前退出循环,或者根据需要分配空间以获取更多结果。这是一个示例:

    char * tstr = str;
    int tok_count = 0;
    char *tok;
    do {
        tok = strtok(tstr, " ");
        if (tok != NULL) {
            token[tok_count++] = tok;
        }
        tstr = NULL;
    } while (tok != NULL && tok_count < TOK_COUNT);

TOK_COUNT必须至少为1,并且应为tokens的数组大小。

答案 1 :(得分:0)

我不知道我是否正确理解你。但是,我只是添加了一些检查以防止在代码的不同点发生段错误。用'foo 3 33'测试。格式不佳。

int main(){


    int ch,  n = 1;
    int i = 0;
    int val = 0;
    #define TOKEN_SZ 5
    char str[512], *token[TOKEN_SZ+1], *act_token;
    while(1){
        printf("Enter text: ");
        while((ch = getchar()) != '\n')
                str[i++] = ch;
        str[i] = '\0';
        i = 0;                

        printf("string: %s\n", str);

        int spaces = 0;
        for(int counter  = 0; counter < strlen(str) + 1; counter++){
                if(str[counter] == ' '){
                        spaces++;
                }
        }
        printf("Spaces: %d\n", spaces); 
        n=0;
        strtok(str, " ");
        while(n<TOKEN_SZ && n <= spaces && (act_token = strtok(NULL, " "))){
                token[n] = act_token;
                n++;
        }
        token[n] = NULL;

        for(int i=0; token[i]; i++){
                printf("%d token[%d]: %s\n", n,i, token[i]);

        } 

        if(n>0 && (atoi(token[0])) != 0){
                val = atoi(token[0]);
        }
        printf("value:%d\n", val);
}
return 0;

}

更新

bash> ./a.out 
Enter text: list 2 4
string: list 2 4
Spaces: 2
2 token[0]: 2
2 token[1]: 4
value:2
Enter text: