我的代码运行/bin/ls -l
,然后将输出打印到终端,我想在这里做的是将输出保存到字符串中供以后使用。我不知道怎么做这个,但从我的猜测看起来会像这样
int main (){
FILE *fp;
int status;
char path[100];
char *s;
fp = popen("/bin/ls -l", "r");
if (fp == NULL){
printf("fp error");
}
while(fgets(path,100,fp)!= NULL){
printf("%s\n", path );
scanf(path, s);
}
status = pclose(fp);
if (status==-1){
printf("pclose error");
}else{
printf("else on pclose\n");
}
return 0;
}
while循环打印出我的目录结果没有问题,但我遇到了一个分段错误:11结束时。解决这个问题的正确方法是什么?
答案 0 :(得分:1)
首先,while(fgets(path,100,fp)!= NULL){
已存储从99
中的管道中读取的第一个path
个字符。没有必要scanf
其他任何内容。
100
是一个非常不足的幻数,要在代码中包含最大路径长度。最好使用PATH_MAX
中定义的limits.h
。 (通常是4096
,但是是实现定义的)。这提出了另一点,不要在代码中使用幻数,如果你需要系统不提供的常量,那么#define
一个,或者使用全局{{1定义它。
使用enum
阅读时,您必须检查并删除(或以其他方式说明)将fgets
填充的缓冲区'\n'
(和POSIX {{ 1}})。这也提供了您实际上读取完整数据行的验证。否则,如果读取的行的长度为fgets
并且末尾没有getline
,则缓冲区的行太长,并且该行的字符在输入流中保持未读。对PATH_MAX - 1
进行简单调用,然后使用'\n'
语句进行检查即可提供验证,并允许您使用 nul-terminatedating 字符覆盖尾随strlen (path)
。
要解决“我需要提供多少文件?”的问题,你可以简单地使用指针指向字符,并动态地为每一行分配指针,根据需要if/else if
个附加指针。您将分配用于存储每一行的每个内存块的地址分配给您分配的各个指针。当你达到极限时,保持对行的计数(对于指针计数)和'\n'
更多的指针(这适用于以相同的方式从文本文件中读取)不要忘记释放你分配的内存完成它。
将所有部分组合在一起,您可以执行以下操作:
realloc
示例使用/输出
realloc
内存使用/错误检查
在你编写的动态分配内存的任何代码中,你有2个职责关于任何分配的内存块:(1)总是保留一个指向起始地址的指针内存块,(2)当不再需要时,它可以释放。
对于Linux #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#define NFILES 16
int main (){
size_t i, n = 0, /* number of files in listing */
nfiles = NFILES; /* number of allocated pointers */
char path[PATH_MAX] = "", /* buffer (PATH_MAX in limits.h) */
**files = NULL; /* pointer to pointer to file */
FILE *fp = popen("/bin/ls -l", "r");
if (fp == NULL) { /* validate pipe open for reading */
perror ("popen");
return 1;
}
/* allocate/validate initial number of pointers */
if (!(files = malloc (nfiles * sizeof *files))) {
perror ("malloc - files");
return 1;
}
while (fgets (path, PATH_MAX, fp)) { /* read each line */
size_t len = strlen (path); /* get length */
if (len && path[len - 1] == '\n') /* validate '\n' */
path[--len] = 0; /* trim '\n' */
else if (len + 1 == PATH_MAX) { /* check path too long */
fprintf (stderr, "error: path too long.\n");
/* handle remaining chars in fp */
}
/* allocate/validate storage for line */
if (!(files[n] = malloc (len + 1))) {
perror ("malloc - files[n]");
break;
}
strcpy (files[n++], path); /* copy path */
if (n == nfiles) { /* realloc pointers as required */
void *tmp = realloc (files, nfiles * 2 * sizeof *files);
if (!tmp) {
perror ("realloc");
break;
}
files = tmp;
nfiles *= 2; /* increment current allocation */
}
}
if (pclose (fp) == -1) /* validate close */
perror ("pclose");
/* print and free the allocated strings */
for (i = 0; i < n; i++) {
printf ("%s\n", files[i]);
free (files[i]); /* free individual file storage */
}
free (files); /* free pointers */
return 0;
}
是正常的选择。每个平台都有类似的记忆检查器。它们都很简单易用,只需通过它运行程序即可。
$ ./bin/popen_ls_files > dat/filelist.txt
$ wc -l dat/filelist.txt
1768 dat/filelist.txt
$ cat dat/filelist.txt
total 9332
-rw-r--r-- 1 david david 376 Sep 23 2014 3darrayaddr.c
-rw-r--r-- 1 david david 466 Sep 30 20:13 3darrayalloc.c
-rw-r--r-- 1 david david 802 Jan 25 02:55 3darrayfill.c
-rw-r--r-- 1 david david 192 Jun 27 2015 BoggleData.txt
-rw-r--r-- 1 david david 3565 Jun 26 2014 DoubleLinkedList-old.c
-rw-r--r-- 1 david david 3699 Jun 26 2014 DoubleLinkedList.c
-rw-r--r-- 1 david david 3041 Jun 26 2014 DoubleLinkedList.diff
<snip>
-rw-r--r-- 1 david david 4946 May 7 2015 workers.c
-rw-r--r-- 1 david david 206 Jul 11 2017 wshadow.c
-rw-r--r-- 1 david david 1283 May 18 2015 wsininput.c
-rw-r--r-- 1 david david 5519 Oct 13 2015 xpathfname.c
-rw-r--r-- 1 david david 785 Sep 30 02:49 xrealloc2_macro.c
-rw-r--r-- 1 david david 2090 Sep 6 02:29 xrealloc_tst.c
-rw-r--r-- 1 david david 1527 Sep 6 03:22 xrealloc_tst_str.c
-rwxr-xr-- 1 david david 153 Aug 5 2014 xsplit.sh
始终确认已释放已分配的所有内存并且没有内存错误。
仔细看看,如果您有其他问题,请告诉我。
答案 1 :(得分:0)
我假设您要将目录保存到字符串数组中。在这种情况下,Image
数组会保留指向所有条目的指针。每个读取条目都将为条目和字符串终止符s[]
分配内存。
启动程序可能如下所示:
\0
这样可行,但我们在堆栈上放了10,000个指针。但是,正如David C. Rankin所建议的那样,我们也可以动态地分配数组#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NR_OF_ENTRIES 10000
#define PATH_LEN 256
int main (){
FILE *fp;
int status;
char path[PATH_LEN];
char *s[MAX_NR_OF_ENTRIES];
int i,j = 0;
fp = popen("/bin/ls -l", "r");
if (fp == NULL){
printf("fp error\n");
}
while(fgets(path,PATH_LEN,fp) != NULL){
printf("%s\n", path );
s[i] = malloc(strlen(path)+1);
strcpy(s[i],path);
i++;
if(i>=MAX_NR_OF_ENTRIES)
{
printf("MAX_NR_OF_ENTRIES reached!\n");
break;
}
}
status = pclose(fp);
if (status==-1){
printf("pclose error");
}else{
printf("pclose was fine!\n");
}
// Print and free the allocated strings
for(j=0; j< i; j++){
printf("%s\n", s[j] );
free (s[j]);
}
return 0;
}
。开始工作计划:
s