尝试连接字符串会产生分段错误

时间:2014-02-10 06:31:39

标签: c gcc

我正在尝试将命令行参数转换为单个char*或“c-string”引用,但似乎我的代码正在破坏。没有任何编译器警告,所以我现在有点卡住了

#include <stdio.h>
#include <string.h>

int main(int argc, char** argv) {
    if (argc < 2) {
        printf("usage: program <arguments>");
        return 0;
    }
    char* string = "";
    for (int i = 1; i < argc; i++) {
        strcat(string, argv[i]);
    }
    printf("%s", string);
    printf("\n");
    return 0;
}

编译:

gcc program.c -Wall -std=c99 -o prog

似乎没有任何警告,所以哪里可能出错?

修改

更新代码:

#include <stdio.h>
#include <string.h>

int main(int argc, char** argv) {
    if (argc == 0) {
        printf("usage: program <arguments>");
        return 1;
    }
    int tot = 0;
    for (int i = 1; i < argc; i++) {
        tot += strlen(argv[i]);
    }
    char string[tot + argc]; // total word length
    strcat(string, "\0");
    for (int i = 1; i < argc; i++) {
        strcat(string, argv[i]);
        strcat(string, " ");
    }
    strcat(string, "\0");
    printf("%s", string);
    printf("\n");
    return 0;
}

然而,出现了一个新问题,因为它似乎在伪字符串前面添加了伪随机垃圾字符。我将此添加到catenation循环中以查看输出:

for (int w = 0; w < sizeof(argv[i]); w++) {
    printf("\t%s%c\n", "char value: ", argv[i][w]);
}

这就是输出:

./prog one two three
    char value: o
    char value: n
    char value: e
    char value:
    char value: t
    char value: w
    char value: o
    char value:
    char value: t
    char value: h
    char value: r
    char value: e
Tëñ¿one two three

所以我的猜测是,问题存在于没有进行\0值的论证中,而是100%确定如何继续。是否会创建一个新的char数组来追加,然后连接适当的?

3 个答案:

答案 0 :(得分:1)

您需要先计算总空间数:

for (int i = 1; i < argc; i++) {
    total += strlen(argv[i]);
}

然后为最终字符串分配空格:

string = calloc(1, total+1);

+1表示空终止符('\ 0') 然后你可以strcat to string,并且当你不再需要它时记得释放它。

这是完整的工作代码(没有错误检查):

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

int main(int argc, char** argv) {
    int total = 0;
    int i;

    if (argc < 2) {
        printf("usage: program <arguments>");
        return 0;
    }
    char *string;
    for (i = 1; i < argc; i++) {
            total += strlen(argv[i]);
    }
    string = calloc(1, total+1);
    for (i = 1; i < argc; i++) {
            strcat(string, argv[i]);
    }   
    printf("%s", string);
    printf("\n");

    free(string);

    return 0;
}

答案 1 :(得分:0)

您声明string的方式使string指向的内存无法修改。

相反,如果您知道所需的最大大小,则可以将string声明为char数组。而且,当你做strcat

时,你需要进行长度检查以确保它不会超限
char string[1024]; // put the size you needed 

或者您可以动态分配空间。正如@moeCake所建议的那样。

答案 2 :(得分:0)

您正在尝试写入文字字符串。两个问题: 1)文字字符串通常不放在可写存储器中。 2)字符串(字符数组)的大小为零;没有空间写信。

快速回答是在堆上分配一个缓冲区:

char* string = (char*)malloc(256);

或在堆栈上:

char string[256];

理想情况下,你应该避免选择像256这样的常量大小。一种方法是循环argv两次 - 一次测量你需要多少空间,然后再次执行副本。