我必须从文件中读取数组,而事实上我是最后一列,只是没有被复制。数组的大小及其内容在文件中。这是代码(仅是问题所在的部分):
#include<stdio.h>
#include<stdlib>
int main(int argc, char * argv[]){
char **laberinto;
char aux;
fent = fopen(argv[1], "r");
if
fprintf(stderr,"Couldn't open.\n");
else
{
laberinto = (char **) calloc(columnas, sizeof(char *));
for (i = 0; (NULL != laberinto) && (i < columnas); i++)
{
laberinto[i] = (char *) calloc(filas, sizeof(char));
if (NULL == laberinto[i])
{
for ( j = i - 1; j >= 0; j-- )
free(laberinto[j]);
free(laberinto);
laberinto = NULL;
}
}
for(i = 0, j = 0; i < filas+1; i++)
for(j = 0; j < columnas+1; j++)
{
if(!feof(fent))
{
aux = fgetc(fent);
if(aux == '\n')
aux = 0;
}}
Edit 1(full code) it generates a core by the way:
#include<stdio.h>
#include<stdlib.h>
#include"encruta1.h"//Just funcion definitions(not used yet)
#define ERRORCOMANDO "ERROR: linea de comandos incorrecta. Utilice:\n"
#define ERRORCOMAND2 "leelabfich fichero_de_entrada columna_inicio fila_inicio\n"
//Both are error messages
int main(int argc, char *argv[])
{
char **laberinto;
char aux;
int i = 0;//Indice para imprimir la tabla
int j = 0;//Indice para imprimir la tabla
int columnas = 0;
int filas = 0;
int flag1;//Para saber si fscanf ha funcionado bien
FILE *fent;
//Si son cuatro argumentos es correcto
if(argc == 4)
{
//Apertura de archivo
fent = fopen(argv[1], "r");
if(fent == NULL)
fprintf(stderr,"No se puede abrir el fichero de entrada.\n");
else
{
flag1 = fscanf(fent,"%d%d", &columnas, &filas);
if(flag1 == 2)
{
if(filas < 0 || columnas < 0)
fprintf(stderr,"Las dimensiones han de ser dos numeros enteros.\n");
else
{
//Reserva de memoria
laberinto = (char **) calloc(columnas, sizeof(char *));
for (i = 0; (NULL != laberinto) && (i < columnas); i++)
{
laberinto[i] = (char *) calloc(filas, sizeof(char));
if (NULL == laberinto[i])
{
for ( j = i - 1; j >= 0; j-- )
free(laberinto[j]);
free(laberinto);
laberinto = NULL;
}
}
//Pasamos el laberinto del archivo a la tabla
for(i = 0, j = 0; i < filas+1; i++)
for(j = 0; j < columnas+1; j++)
{
if(!feof(fent))
{
aux = fgetc(fent);
if(aux == '\n')
aux = 0;
else
laberinto[i][j] = aux;
}
}
for(i = 0; i < filas; i++)
{
for(j = 0; j < columnas; j++)
{//Eliminamos los intentos fallidos
if(laberinto[i][j] == 'o')//Just ignore the o
laberinto[i][j] = '.';
printf("%c", laberinto[i][j]);
}
printf("\n");
}
//Sustituir por donde se libere memoria abajo
for(i = 0; i < columnas+1; i++)
free(laberinto[i]);
laberinto = NULL;
最佳答案
使用面向行的输入将文件中的所有行读入动态分配的数组中,可以为您提供更好的服务。标准库中可用的面向行的函数是fgets
和getline
。
在这种情况下,如果您不知道每行的最大字符数,最好使用getline
读取每行,因为getline
将为您动态分配足够大小的行缓冲区。
如果使用fgets
(很好),则必须添加代码以检查每行以及realloc
和strcat
行的短读或不完整读,直到完全读完为止。 getline
只是使生活更简单。
您的基本方案是声明一个指向类型的指针(即双指针),分配合理数量的指针来处理文件,如果达到初始限制,则realloc
2X
该数字当前指针并继续。
完成后,释放分配的行,然后释放数组。一个简单的例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NMAX 128 /* initial number of pointers */
int main (int argc, char **argv) {
char **array = NULL; /* array to hold lines read */
char *ln = NULL; /* NULL forces getline to allocate */
size_t n = 0; /* initial ln size, getline decides */
ssize_t nchr = 0; /* number of chars actually read */
size_t idx = 0; /* array index counter */
size_t nmax = NMAX; /* check for reallocation */
size_t i = 0; /* general loop variable */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin; /* open stream */
if (!fp) { /* validate stream open for reading */
fprintf (stderr, "error: file open failed '%s',\n", argv[1]);
return 1;
}
/* allocate NMAX pointers to char* */
if (!(array = calloc (NMAX, sizeof *array))) {
fprintf (stderr, "error: memory allocation failed.");
return 1;
}
/* read each line from fp */
while ((nchr = getline (&ln, &n, fp)) != -1)
{
/* strip newline or carriage rtn */
while (nchr && (ln[nchr-1] == '\n' || ln[nchr-1] == '\r'))
ln[--nchr] = 0;
array[idx++] = strdup (ln); /* allocate/copy ln to array */
if (idx == nmax) { /* if idx reaches nmax, reallocate */
char **tmp = realloc (array, nmax * 2 * sizeof *tmp);
if (!tmp) {
fprintf (stderr, "error: memory exhausted.\n");
break;
}
array = tmp; /* set new pointers NULL */
memset (array + nmax, 0, nmax * sizeof tmp);
nmax *= 2;
}
}
if (ln) free (ln); /* free memory allocated by getline */
if (fp != stdin) fclose (fp); /* close open file if not default */
/* print array */
printf ("\n lines read from '%s'\n\n", argc > 1 ? argv[1] : "stdin");
for (i = 0; i < idx; i++)
printf (" line[%3zu] %s\n", i, array[i]);
for (i = 0; i < idx; i++)
free (array[i]); /* free each line */
free (array); /* free pointers */
return 0;
}
使用内存错误检查器(如Linux上的
valgrind
)确认内存的正确使用,并在不再需要时正确释放了所有内存。查看一下,如果您还有其他问题,请与我们联系。数值数组
对于数字数组,您采用的方法完全相同。但是,不是将
ln
存储在指向char的指针数组中,而是只需根据需要使用sscanf
或最好是strtol
等来解析行,...所需的更改很小。例如。:...
#include <limits.h>
#include <errno.h>
...
long *array = NULL; /* pointer to long */
int base = argc > 2 ? atoi (argv[2]) : 10; /* base (default: 10) */
...
您的读取循环如下所示:
/* read each line from file - separate into array */
while ((nchr = getline (&ln, &n, fp)) != -1)
{
char *p = ln; /* pointer to ln read by getline */
char *ep = NULL; /* endpointer for strtol */
while (errno == 0)
{ /* parse/convert each number in line into array */
array[idx++] = xstrtol (p, &ep, base);
if (idx == nmax) /* check NMAX / realloc */
array = realloc_long (array, &nmax);
/* skip delimiters/move pointer to next digit */
while (*ep && *ep != '-' && (*ep < '0' || *ep > '9')) ep++;
if (*ep)
p = ep;
else
break;
}
}
用于验证到
long
和realloc
的转换的辅助函数可以写为:/* reallocate long pointer memory */
long *realloc_long (long *lp, unsigned long *n)
{
long *tmp = realloc (lp, 2 * *n * sizeof *lp);
if (!tmp) {
fprintf (stderr, "%s() error: reallocation failed.\n", __func__);
// return NULL;
exit (EXIT_FAILURE);
}
lp = tmp;
memset (lp + *n, 0, *n * sizeof *lp); /* memset new ptrs 0 */
*n *= 2;
return lp;
}
注意:您可以调整是否在内存耗尽时返回
NULL
或exit
以满足您的需要。对于转换,可以通过strtol
使用简单的错误检查,如下所示。/* simple strtol wrapper with error checking */
long xstrtol (char *p, char **ep, int base)
{
errno = 0;
long tmp = strtol (p, ep, base);
/* Check for various possible errors */
if ((errno == ERANGE && (tmp == LONG_MIN || tmp == LONG_MAX)) ||
(errno != 0 && tmp == 0)) {
perror ("strtol");
exit (EXIT_FAILURE);
}
if (*ep == p) {
fprintf (stderr, "No digits were found\n");
exit (EXIT_FAILURE);
}
return tmp;
}
我已经放置了一个完整的示例,说明如何在pastbin中将文件读取到动态分配的long的2D数组中:C - read file into dynamically allocated 2D array
关于c - 如何从文件复制到数组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34688545/