c - 访问字符数组时出现段错误

标签 c arrays segmentation-fault

给定一个数字列表和一个正整数 k,我必须反转列表的元素,一次 k 个项目。如果元素数量不是k的倍数,则最后剩余的项目应保持原样:

例如: 输入:1,2,3,4,5;2

输出:2,1,4,3,5

我使用了一个非常简单的概念,我将两端的两个指针 a&b 进行交换,并在整个循环中迭代它们。

我遇到段错误。我该如何纠正?

我的代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void reverse(char str[],int p)
{
    int i,j,k,a,b;
    int len=strlen(str);
    printf("%d\n",len);
    a=0;
    b=p-1;
    while(1)
    {
        i=a;j=b;
        while(j>i)
        {
          k=str[i];
          str[i]=str[j];
          str[j]=k;
          i++;
          j--;
        }
        a=a+p;
        b=b+p;
        if(b>=len)
        break;  
    }
    for(i=0;i<len-1;i++)
    printf("%c,",str[i]);
    if(i==len-1)
    printf("%c",str[i]);
    printf("\n");
}
int main(int argc,char* argv[])
{
    if(argc!=2)
    {
        printf("Wrong number of arguments\n");
        exit(0);
    }
    FILE *fp;
    fp=fopen(argv[1],"r");
    if(fp==NULL)
    {
        printf("File can't be openend:\n");
        exit(0);
    }
    char c;
    c=fgetc(fp);
    char str[100];
    memset(str,'0',100);
    int k,i;
    while(1)
    {
        k=0;
        while(c!=';')
        {
          if(c!=',')
          {
            str[k]=c;
            k++;
            c=fgetc(fp);
          }
          else
          c=fgetc(fp);
        }
        str[k]='\0';
        c=fgetc(fp);
        int p=c-'0';
        reverse(str,p);
        c=fgetc(fp);
        if(c==EOF)
        break;
        else
        c=fgetc(fp);
    }
    return 0;
}

谢谢!

最佳答案

可能还有其他方法可以做到这一点,但这段代码可以工作。您在 reverse() 中的算法方面做得很好。在 reverse() 函数中,唯一的更改是代码格式设置和添加更完整的诊断打印。 main() 函数被重写为使用 fgets() 读取一行,然后解析该行。如果不出意外的话,这样做可以更容易地报告错误的输入(例如,尽管代码无法在不包含分号的行上正确报告,并且代码假定 a 处的 k 项时间始终是单个数字,并且不强制要求用逗号分隔单个数字,并且...)。

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

static void reverse(char str[], int p)
{
    int i, j, k, a, b;
    int len = strlen(str);
    printf("Input:  %d: %s (%d)\n", len, str, p);
    a = 0;
    b = p - 1;
    while (1)
    {
        i = a;
        j = b;
        while (j > i)
        {
          k = str[i];
          str[i] = str[j];
          str[j] = k;
          i++;
          j--;
        }
        a = a + p;
        b = b + p;
        if (b >= len)
            break;  
    }
    printf("Output: ");
    for (i = 0; i < len - 1; i++)
        printf("%c, ", str[i]);
    if (i == len - 1)
        printf("%c", str[i]);
    printf("\n");
}

int main(int argc, char* argv[])
{
    if (argc != 2)
    {
        printf("Wrong number of arguments\n");
        exit(1);
    }
    FILE *fp = fopen(argv[1], "r");
    if (fp == NULL)
    {
        printf("File can't be openend:\n");
        exit(1);
    }
    char line[100];
    while (fgets(line, sizeof(line), fp) != 0)
    {
        printf("Read:   %s", line);
        fflush(0);
        char str[100];
        int k = 0;
        int i = 0;
        char c;
        while ((c = line[i++]) != '\0')
        {
            if (c == ';')
                break;
            else if (c == ',')
                continue;
            else
                str[k++] = c;
        }
        str[k] = '\0';
        printf("String: %s\n", str);
        if (c == ';')
        {
            c = line[i];
            int p = c - '0';
            reverse(str, p);
        }
    }
    fclose(fp);
    return 0;
}

示例输入数据

1,2,3,4,5;2
1,2,3,4,5,6,7;3
1,2,3,4,5,6,7,8,9;2
1,2,3,4,5,6,7,8,9;3
1,2,3,4,5,6,7,8,9;4
1,2,3,4,5,6,7,8,9;5

示例输出

Read:   1,2,3,4,5;2
String: 12345
Input:  5: 12345 (2)
Output: 2, 1, 4, 3, 5
Read:   1,2,3,4,5,6,7;3
String: 1234567
Input:  7: 1234567 (3)
Output: 3, 2, 1, 6, 5, 4, 7
Read:   1,2,3,4,5,6,7,8,9;2
String: 123456789
Input:  9: 123456789 (2)
Output: 2, 1, 4, 3, 6, 5, 8, 7, 9
Read:   1,2,3,4,5,6,7,8,9;3
String: 123456789
Input:  9: 123456789 (3)
Output: 3, 2, 1, 6, 5, 4, 9, 8, 7
Read:   1,2,3,4,5,6,7,8,9;4
String: 123456789
Input:  9: 123456789 (4)
Output: 4, 3, 2, 1, 8, 7, 6, 5, 9
Read:   1,2,3,4,5,6,7,8,9;5
String: 123456789
Input:  9: 123456789 (5)
Output: 5, 4, 3, 2, 1, 6, 7, 8, 9

调试原始版本

如果您必须调试原始代码,那么我添加的 reverse() 中的诊断打印将会有所帮助。在 main() 代码中,您需要考虑在每个字符到达时对其进行回显,并且可能打印 str 数组。你需要小心,因为你用零填充了它。您可以使用 printf("String: %.*s\n", k, str); 将输出限制为 str< 的前 k 个字符.

关于c - 访问字符数组时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15942147/

相关文章:

c - 你如何将文本文件中的数据导入MATLAB来制作圆锥体?

c - fclose() 期间的段错误

Java 和 PostgreSQL 数组

C++ 'substitute' 用于具有灵活数组成员的结构

C 程序接收到信号 SIGSEGV,矩阵乘法时出现段错误?

c - C 中的基本重命名语句异常行为

Android 套接字每 20 秒卡住一次

c - C 函数中的数组参数 & 返回什么类型?

c - 初学者内联程序集段错误

c++ - 在 CLion 中调试时程序收到段错误