我在程序中发现了段错误,我感到很茫然

时间:2014-10-07 12:45:41

标签: c

所以我花了好几个小时试图找到这个分段错误11错误的来源,我希望你们能帮助我。

因此,程序的目的是在输入字符串中查找重定向,并返回一个redirCode结构,该结构提供重定向方向,fileName和argsWithoutFile。

示例输入:

"ls -a > test.txt"

返回带有以下内容的redir代码:

argsWithoutFile = "ls -a"
fileName = "test.txt"
code = 2                     //stdout

我很确定seg故障来自于尝试做子串。 for循环看起来很好,因为当我在最后注释掉子串的东西时,它不会给出段错误。除了子串外,一切似乎都很好。基本上对于子字符串我希望它是这样的:

char *input = "ls -a > test.txt'
char *desiredSubString = "ls -a "

以下是完整的代码:

#include <stdio.h>
#include <string.h>
#define BUFFER      1024
struct redirCode findRedirects(char *input);
struct redirCode {
    /* For code:
     * 0 = none
     * 1 = stdin
     * 2 = stdout
     */
    int code;
    char *argsWithoutFile;
    char *fileName;
};

int main(){
    const char *delims = "<>";
    struct redirCode temp;
    char line[BUFFER];

    printf("Input: ");
    fgets(line, 1024, stdin);
    temp = findRedirects(line);

    printf("temp:\n");
    printf("temp.code = %d\n", temp.code);
    printf("temp.fileName = %s\n", temp.fileName);
    printf("temp.argsWithoutFile = %s\n", temp.argsWithoutFile);

}

/* Looks for '>', '<' in a string.
 * Will destroy string *input
 * Returns a redirCode struct with:
 * 1. fileName - the name of file that
 * wants to be redirected/stdin
 * 2. code - the direction of redirect
 * 3. args - the arguments w/o filename
 * */
struct redirCode findRedirects(char *input)
{
    const char *delims = "<>";
    struct redirCode redirToReturn;

    //Do an initial search for the delimeters
    //before strtok destroys it. O(n) time.
    int redirectOperatorReached = 0;
    int count = 0;

    int i;
    for (i = 0; input[i] != 0; i++){
        if (input[i] == '<'){
            redirToReturn.code = 1;
            redirectOperatorReached = 1;
        }
        else if (input[i] == '>'){
            redirToReturn.code = 2;
            redirectOperatorReached = 1;
        }
        else {
            redirToReturn.code = 0;
        }
        if (redirectOperatorReached != 1){
            count++;
        }
    }
    printf("sizeof(input) = %lu\n", sizeof(input));
    printf("count = %d\n", count);
    strncpy(redirToReturn.argsWithoutFile, input, count);
    printf("input = %s\n", input);
    redirToReturn.argsWithoutFile[count] = '\0';
    printf("argsW/oFile = %s\n", redirToReturn.argsWithoutFile);

    return redirToReturn;
}

以下是一些终端日志

MacBook-Air:practice keithy$ cc strtokOnlyOnce.c
MacBook-Air:practice keithy$ ./a.out
Input: hi
sizeof(input) = 8
count = 3
Segmentation fault: 11
MacBook-Air:practice keithy$ cc strtokOnlyOnce.c
MacBook-Air:practice keithy$ ./a.out
Input: ls -a > test.txt
sizeof(input) = 8
count = 6
Segmentation fault: 11
MacBook-Air:practice keithy$

编辑:我让它上班了!我所要做的就是在redirCode中使用malloc字符串。这是工作代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUFFER      1024
struct redirCode findRedirects(char *input);
struct redirCode {
    /* For code:
     * 0 = none
     * 1 = stdin
     * 2 = stdout
     */
    int code;
    char *argsWithoutFile;
    char *fileName;
};

int main(){
    const char *delims = "<>";
    struct redirCode temp;
    char line[BUFFER];

    printf("Input: ");
    fgets(line, 1024, stdin);
    temp = findRedirects(line);

    printf("temp.code = %d\n", temp.code);
    printf("temp.fileName = %s\n", temp.fileName);
    printf("temp.argsWithoutFile = %s\n", temp.argsWithoutFile);

}

/* Looks for '>', '<' in a string.
 * Will destroy string *input
 * Returns a redirCode struct with:
 * 1. fileName - the name of file that
 * wants to be redirected/stdin
 * 2. code - the direction of redirect
 * 3. args - the arguments w/o filename
 * */
struct redirCode findRedirects(char *input)
{
    const char *delims = "<>";
    struct redirCode *redirToReturn = malloc(sizeof(struct redirCode));

    //Do an initial search for the delimeters
    //before strtok destroys it. O(n) time.
    int redirectOperatorReached = 0;
    int count = 0;

    int i;
    for (i = 0; input[i] != 0; i++){
        if (input[i] == '<'){
            redirToReturn->code = 1;
            redirectOperatorReached = 1;
            input[i] = ' ';
        }
        else if (input[i] == '>'){
            redirToReturn->code = 2;
            redirectOperatorReached = 1;
            input[i] = ' ';
        }
        if (redirectOperatorReached != 1){
            count++;
        }
    }
    int lengthOfInput = strlen(input);

    int sizeOfMalloc = (lengthOfInput+1)*sizeof(char);
    redirToReturn->argsWithoutFile = (char *) malloc(sizeOfMalloc);
    redirToReturn->fileName = (char *) malloc(sizeOfMalloc);

    strncpy(redirToReturn->argsWithoutFile, input, count);
    redirToReturn->argsWithoutFile[count] = '\0';

    strncpy(redirToReturn->fileName, input + count, lengthOfInput - count);

    return *redirToReturn;
}

/*OUTPUT
 *./a.out
 *Input: ls -a > test.txt
 *temp.code = 2
 *temp.fileName =   test.txt
 *temp.argsWithoutFile = ls -a
*/

2 个答案:

答案 0 :(得分:1)

1→ 您需要为argsWithoutFile分配内存  在执行new之前使用malloc / strncpy 2→ filename未初始化,您将其打印在printf中。这是未定义的行为。

答案 1 :(得分:1)

  struct redirCode {
        /* For code:
         * 0 = none
         * 1 = stdin
         * 2 = stdout
         */
        int code;
        char *argsWithoutFile;
        char *fileName;
    };

在使用之前,您需要为名为char *argsWithoutFile;char *fileName;的结构成员分配内存。

你可以这样做

struct redirCode *redirToReturn = malloc(sizeof(struct redirCode ));
redirToReturn->argsWithoutFile = malloc(1024);
redirToReturn->fileName = malloc(1024);