为什么我的程序出现分段错误?

时间:2020-11-12 12:06:08

标签: c

我必须编写一个程序,将日期和待办事项作为命令行参数读取,并将它们放在文本文件中(逐行)。

正确输入:

./todo 13:58 todo1 00:00 todo2 08:30 todo3

输入错误:

./todo 13:58 todo1 24:00 todo2 08:30 todo3 or ./todo 13:58 todo1 todo2 00:00 08:30 todo3

纠正 todolist.txt 文件:

13:58 - todo1
00:00 - todo2
08:30 - todo3

代码已成功编译,但是当我运行程序时,出现了分段错误:

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

bool isValidTime(char* argv)
{
    char hour[2] = {0};
    char minute[2] = {0};

    for (unsigned int i = 0; argv[i] != ':'; i++) {
        hour[i] = argv[i];
    }
    int hourNum = atoi(hour);
    if (!(hourNum >= 0 && hourNum < 24)) {
        return false;
    }

    for (unsigned int i = 3; i < sizeof(*argv) / sizeof(argv[0]); i++) {
        minute[i] = argv[i];
    }
    int minuteNum = atoi(minute);
    if (!(minuteNum >= 0 && minuteNum < 60)) {
        return false;
    }

    return true;
}

bool isValidTodo(char* argv)
{
    for (unsigned int i = 0; i < sizeof(*argv) / sizeof(argv[0]); i++) {
        if (!(argv[i] >= 'a' && argv[i] <= 'z')) {
            return false;
        }
    }
    return true;
}

int main(int argc, char* argv[])
{
    if (argc < 3) {
        printf("Incorrect input!\n");
        return 1;
    }
    
    FILE* file;
    file = fopen("todolist.txt", "w");
    if (file == NULL) {
        printf("File failed to open.\n");
        return 1;
    }

    for (int i = 1; i < argc; i++) {
        if (!(isValidTime(argv[2 * i - 1]) && isValidTodo(argv[2 * i]))) {
            printf("Incorrect input!\n");
        }
        fprintf(file, "%s - %s\n", argv[2 * i - 1], argv[2 * i]);
    }

    fclose(file);

    return 0;
}

1 个答案:

答案 0 :(得分:1)

很可能是因为以下代码:

for (int i = 1; i < argc; i++) {
    if (!(isValidTime(argv[2 * i - 1]) && isValidTodo(argv[2 * i]))) {
        printf("Incorrect input!\n");
    }
    fprintf(file, "%s - %s\n", argv[2 * i - 1], argv[2 * i]);
}

您将获得argc个参数,但是随后您将使用argv[2 * i - 1]为数组建立索引。假设您有4个参数-您将尝试为元素2 * 4 - 1(即元素7)建立索引,该元素将位于数组之外,从而导致分段错误。

如果您的目标是对先前和当前元素进行某些操作,则可能只需删除2 *部分。

我看到的另一个问题是此代码:

for (unsigned int i = 0; argv[i] != ':'; i++) {
    hour[i] = argv[i];
}

如果参数中没有:,则将无限期循环,并且会为hour[i]argv[i]产生另一个分段错误。

相关问题