Das Problem ist nicht der Name der Datei, es ist, dass die Dateien unterschiedlichen Inhalt haben. Dieser unterschiedliche Inhalt macht die Speicherprobleme in Ihrem Code verfügbar.
Sofort geht mein Auge auf die hartcodierte 361
überall. Dies setzt voraus, dass in der Eingabedatei 361 Zeilen stehen und dass Ihr Segfault vorhanden ist. Es passiert in Zeile 40 (identifiziert mit valgrind), wenn val = atof(result[k]);
aus dem result
Array geht. Es ist sehr verlockend in C zu harten Codegrößen. Tun Sie es nicht, vor allem für die Eingabe, es ist eine Krücke, auf die Sie sich nicht verlassen können.
Stattdessen muss der Code an die Anzahl der Felder und Zeilen in der Datei angepasst werden. Sie können Ihren eigenen dynamischen Array-Code mit realloc
schreiben, aber es gibt viele C-Bibliotheken, die dies für Sie tun werden, und viel besser. Ich erreiche für GLib für die Grundlagen.
Ein weiteres Problem ist, dass Sie nur 10 Bytes für jede Zeile zugewiesen haben. Das ist sehr klein. Es bedeutet fgets
ist ständig von line
gehen, wenn es länger als 9 Zeichen (was es sein wird). Jede Art von statischer Speicherzuweisung beim Lesen von Eingabe wird ein Problem sein. Die Verwendung von getline
anstelle von fgets
vermeidet das Problem, wie viel Speicher pro Zeile zugewiesen werden muss. getline
kümmert sich darum für Sie. Seien Sie vorsichtig, getline
wiederverwendet line
, wenn Sie also line
ändern möchten, müssen Sie zuerst strdup
es.
/*
* Calibration File Read Test
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <glib.h>
int main (int argc, char **argv)
{
/* Check we got the right number of arguments. */
if(argc != 2) {
fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
return -1;
}
/* Open the file */
FILE *fp = fopen (argv[1], "r");
if(fp == NULL)
{
fprintf(stderr, "Error opening file %s for reading.\n", argv[1]);
return(-1);
}
/* A dynamic array which will grow as needed */
GArray *result = g_array_new(TRUE, TRUE, sizeof(char *));
/* Read each line using getline which does the line memory allocation
for you. No buffer overflow to worry about. */
char *line = NULL;
size_t linecap = 0;
while(getline(&line, &linecap, fp) > 0) {
/* This will only read the first cell. Exercise left for the reader. */
char *value = strtok(line, ",");
if(value == NULL) {
fprintf(stderr, "Could not parse %s\n", line);
continue;
}
char *field = malloc(strlen(value) + 1);
strcpy(field, value);
g_array_append_val(result, field);
}
free(line);
fclose(fp);
/* Iterate through the array using result->len to know the length */
for(int i = 0; i < result->len; i++)
{
printf("Element[%d] = %s\n", i, g_array_index(result, char *, i));
}
/* Free the array */
g_array_free(result, TRUE);
return 0;
}
Ich habe die atof
Umwandlung, weil es eine Ablenkung von dem Hauptproblem abgezogen. Sie können das zurückstellen, wenn Sie möchten.
Dies hat immer noch das Problem, dass es nur die erste Zelle jeder Zeile liest. Ich überlasse es dir das zu tun.
Verwenden Sie einfach 'sscanf', um aus einer Zeichenkette zu scannen, die eine Art Regex unterstützt, lesen Sie hier: http://www.cplusplus.com/reference/cstdio/scanf/ – k06a
Ich würde vorschlagen, dass Sie Ihre .txt und. CSV-Dateien. Ich würde denken, dass sie in jeder Hinsicht identisch sein sollten, außer für die Dateinamenerweiterung, und wenn Ihr Code für einen funktioniert, sollte er für den anderen funktionieren. – Logicrat
[Strcpy nicht verwenden] (http://stackoverflow.com/questions/5122882/strcpy-string-array) Wenn Sie die Notizen in der [man page for strcpy] (http://linux.die.net/man/3/strcpy) es macht Sinn, warum du dich davon fern halten willst. –