【问题标题】:Combine two strings into one in C programming在C编程中将两个字符串合二为一
【发布时间】:2014-11-17 07:06:37
【问题描述】:

我在 C 编程中组合两个字符串时遇到困难,我希望能够从命令行参数中获取输入文件名,并将 .out 添加到文件名中作为输出文件的新名称。例如Test1.txt -> Test1.txt.out

以下代码由于未知原因产生分段错误。

int main(int argc, char** argv)
{
    char fileName_Out[200];
    Consortium *con1;   
    int i;

    for(i=0; i<argc; i++)
    {
        strcpy(fileName_Out, argv[i]);
        strcat(fileName_Out, ".out");
        con1 = readConsortium (argv[i]);
        writeNetWorth (fileName_Out, con1);
    }


    free(con1->core);
    free(con1->associate);
    free(con1);
    con1->core = NULL;
    con1->associate = NULL;
    con1 = NULL;

    return 0;
}

更新整个代码:

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

typedef struct {
    char code[4];
    float sharePrice;
    int shares;
    float assetValue;
    float debts;
} Company;

typedef struct {
    int numCore;
    int numAss;
        Company* core;
        Company* associate;
} Consortium;

Consortium *readConsortium (char* fileName) {

    Consortium *con1 = (Consortium*)malloc(sizeof(Consortium));
    int i;
    FILE *source_f = fopen(fileName, "r");

    if(source_f == NULL)
    {
        con1 = NULL;
    } else {

    fscanf(source_f, "%d %d", &(con1->numCore), &(con1->numAss));  

    con1->core = (Company*)malloc(sizeof(Company)*(con1->numCore));
    con1->associate = (Company*)malloc(sizeof(Company)*(con1->numAss));

    for(i = 0; i < con1->numCore; i++)
    {
        fscanf(source_f, "%s %f %d %f %f", con1->core[i].code, &con1->core[i].sharePrice, &con1->core[i].shares, &con1->core[i].assetValue, &con1->core[i].debts); 
    }

    for(i = 0; i < con1->numAss; i++)
    {
        fscanf(source_f, "%s %f %d %f %f", con1->associate[i].code, &con1->associate[i].sharePrice, &con1->associate[i].shares, &con1->associate[i].assetValue, &con1->associate[i].debts); 
    }

    }

    fclose(source_f);

    return con1;
}

void writeNetWorth (char* fileName_Out, Consortium *con)
{
    int i;
    float netWorth;
    FILE* target_f = fopen(fileName_Out, "w");

    for(i = 0; i < con->numCore; i++)
    {
        netWorth = (con->core[i].sharePrice * con->core[i].shares) + con->core[i].assetValue - con->core[i].debts;
        fprintf(target_f, "%s:%12.2f\n", con->core[i].code, netWorth); 
    }

    for(i = 0; i < con->numAss; i++)
    {
        netWorth = (con->associate[i].sharePrice * con->associate[i].shares) + con->associate[i].assetValue - con->associate[i].debts;
        fprintf(target_f, "%s:%12.2f\n", con->associate[i].code, netWorth); 
    }

    fclose(target_f);
}

/* int main(void)
{
    char fileName[200];
    char fileName_Out[200];
    Consortium *con2;

    scanf("%s %s", fileName, fileName_Out);

    con2 = readConsortium (fileName);
    writeNetWorth (fileName_Out, con2);

    free(con2->core);
    free(con2->associate);
    free(con2);
    con2->core = NULL;
    con2->associate = NULL;
    con2 = NULL;
    return 0;   
}*/

int main(int argc, char** argv)
{
    char fileName_Out[200];
    Consortium *con1;   
    int i;

    for(i=1; i<(argc+1); i++)
    {
        strcpy(fileName_Out, argv[i]);
        strcat(fileName_Out, ".out");
        con1 = readConsortium (argv[i]);
        writeNetWorth (fileName_Out, con1);
    }


    free(con1->core);
    free(con1->associate);
    free(con1);
    con1 = NULL;

    return 0;
}

【问题讨论】:

  • 使用gdb 找出崩溃的位置和原因。
  • 释放后通过-&gt;访问con1,这是不应该的。 con1 = NULL; 就够了。
  • 您可能希望以argv[1] 开头,因为argv[0] 是您的程序的名称。
  • 使用 GDB 时,我会在程序运行后立即收到 SIGSEGV 消息,这是否意味着在程序开始时发生了段错误?
  • 没有断点,无论当前执行在哪一行,你都会得到一个段错误总是as soon as the program is run..

标签: c for-loop segmentation-fault strcpy strcat


【解决方案1】:

两件事。

  1. 您确定在使用 fileName_Out[200] 时没有耗尽内存吗?来自strcat()man page

    dest 字符串必须有足够的空间用于结果。如果 dest 不够大,程序行为是不可预测的;

  2. 在您显示的代码中,您似乎从未为con1 指针分配内存。 [考虑到您没有向我们展示readConsortium() 定义]。

  3. 我认为您应该避免使用free-ing con1-&gt; ..,因为在您的main() 中没有分配给con


编辑:

您的问题出在代码的其他地方。使用 for 循环指定

for(i=1; i<(argc+1); i++)

你已经越界了。将该条件更改为

for(i=1; i<argc; i++).

请记住,数组中的nth 元素的索引始终为n-1

【讨论】:

  • con1 在 writeNetWorth 函数中分配了内存,删除 strcat 和 strcpy 函数不会显示段错误,输入文件名小于字符串长度 99。
  • @IamTrent 您必须在问题中包含这些功能,否则没有人能够回答。错误很可能在这些函数中。
  • 删除strcpy和strcat后,其余功能正常工作,所以问题不大。无论如何我都会包括它们。
  • @IamTrent 你注意到for(i=1; i&lt;(argc+1); i++)了吗?不应该是for(i=1; i&lt;argc; i++)吗?
  • @IamTrent 以及您发布的完整代码,看起来不错。我会编辑我的答案。 :-)
【解决方案2】:

在我看来,con1 似乎变成了 NULL,但您尝试在 writeNetWorth 中使用该指针而不检查 NULL。

for(i = 0; i &lt; con-&gt;numCore; i++)

con 为 NULL 时会导致段错误。

con1 变为 NULL 的原因很可能是你无法打开你从 "argv[0].out" 得到的 yourprogram.exe.out。

附带说明一下,您的程序似乎也存在内存泄漏,在循环中动态分配内存而不在同一循环中释放内存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-25
    • 1970-01-01
    • 1970-01-01
    • 2017-06-23
    相关资源
    最近更新 更多