0

所以我应该创建一个函数来完成: 目的:程序来打乱文本文件的行

  • 将文件读入数组
  • 计数行和最大长度
  • 计算数组的最大宽度
  • 获取指向开头的文件指针
  • 为动态字符串数组保留内存
  • 读取一行并存储在分配的内存中
  • 把 \n 变成 \0
  • 从数组打印行(测试)
  • 洗牌数组
  • 从数组打印行(测试)
  • 释放内存并关闭文件

(只是提供一些背景)

但是,当我打印洗牌后的数组时,会出现分段错误。有时,它会打印一两个字符串,但有时它只是说“Shuffled Array”,然后我得到一个分段错误。有任何想法吗?

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

// Accepts: command line input
// Returns: 0 if no error

int main(int argc, char *argv[] ){
    int x = 0, i, lineCount = 0, maxLen = 0;
    char line[500], temp;
    FILE *file = fopen( argv[1], "r" );
//  check if file exists
    if (file == NULL){
        printf("Cannot open file\n");
        return 1;
    }
//  Gets lines, max length of string    
    while (fgets(line, sizeof(line), file) != NULL){
        lineCount++;
        if (strlen(line) > maxLen)
            maxLen = strlen(line);
    }
    rewind(file);
    char *lineArray[lineCount];
    while (fgets(line, sizeof(line), file) != NULL) {
            lineArray[x] = malloc(strlen(line));
        if (lineArray[x] == NULL){
            printf("A memory error occurred.\n");
            return(1);
        }
            strcpy(lineArray[x], line);
//  change \n to \0
        lineArray[x][strlen(lineArray[x])-1] = '\0';
        x++;
    }
    printf("File %s has %d lines with maximum length of %d characters\n",
        argv[1], lineCount, maxLen);
    printf("Original Array\n");
    for (x = 0; x < lineCount; x++)
        printf("%2d %s\n", x, lineArray[x]);
//  Shuffle array
    srand( (unsigned int) time(NULL));
    for (x = lineCount - 1; x >= 0; x--){
        i = (int) rand() % lineCount;
        temp = lineArray[x];
        lineArray[x] = lineArray[i];
        lineArray[i] = temp;
    }
    printf("\nShuffled Array\n");
    for (x = 0; x < lineCount; x++)
        printf("%2d %s\n", x, lineArray[x]);
//  free allocated memory
    for (x = 0; x < lineCount; x++)
        free(lineArray[x]);
    free(lineArray);
    fclose(file);
    return 0;
}
4

2 回答 2

1

在我的机器上运行的输出cc使错误非常明显。

$ cc tmp.c -o tmp
tmp.c:46:14: warning: incompatible pointer to integer conversion assigning to
      'char' from 'char *'; dereference with * [-Wint-conversion]
        temp = lineArray[x];
             ^ ~~~~~~~~~~~~
               *
tmp.c:48:22: warning: incompatible integer to pointer conversion assigning to
      'char *' from 'char'; take the address with & [-Wint-conversion]
        lineArray[i] = temp;
                     ^ ~~~~
                       &
2 warnings generated.

你需要修复你的变量,你不能char在你打算使用的地方使用char *.

对不起,为了更清楚:

char line[500], temp;

应该:

 char line[500], *temp;

如果您想澄清这是为什么,请告诉我。

最后,在方法的顶部声明变量不是 C 风格的(除非您正在编写嵌入式 C)。将它们声明为尽可能靠近使用点。它使您更容易找到您声明的内容。例如,temp可以在使用它的循环的正上方声明,或者更好的是,在循环本身中声明。

哦,还有:

$ cc --version
Apple LLVM version 5.0 (clang-500.2.76) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix
于 2013-10-27T22:06:44.520 回答
0

你在这里做什么?

free(lineArray);

lineArray是一个数组,定义如下:

char *lineArray[lineCount];

你不应该尝试free()它,因为你一开始就没有malloc()这样做。

最重要的是,这个:

char line[500], temp;

应该是这样的:

char line[500], *temp;

正如您的编译器应该试图告诉您的那样。

可能还有其他问题,但是由于您选择不提供输入文件或提供不需要的程序版本,因此没有人可以编译并运行它来找出答案。

编辑:进行上述更改,按照另一个答案的建议更改lineArray[x] = malloc(strlen(line));lineArray[x] = malloc(strlen(line) + 1);,并使用合适的输入文件,我得到以下输出:

paul@local:~/src/c/scratch$ ./sta testfile
File testfile has 4 lines with maximum length of 13 characters
Original Array
 0 john doe
 1 jane fish
 2 donny brutus
 3 fishy mcgee

Shuffled Array
 0 john doe
 1 jane fish
 2 fishy mcgee
 3 donny brutus
paul@local:~/src/c/scratch$

不过,你真的需要学习更好地使用你的编译器。你应该像这样调用 gcc:

gcc -o myprog myfile.c -std=c99 -pedantic -Wall -Wextra

获得所有最有用的警告。

于 2013-10-27T22:06:41.730 回答