动态数组字符串在C中

huangapple go评论63阅读模式
英文:

Dynamic array strings in c

问题

我有一个任务,我应该逐行读取一个文本文件,然后我应该颠倒每一行(每行包含一个字符串),同时我还必须颠倒行的顺序,所以最后一行应该成为第一行,倒数第二行应该成为第二行,依此类推,并且我必须将所有这些写入标准输出。

首先,我应该从argv[]中读取一个枚举值f,它可以是"linenums"或"nolinenums",如果是"nolinenums",我就没有什么要做的,但如果是"linenums",我必须反向编号行。然后,一个整数和其他参数应该是文件的名称。

例如:./main linenums 5 example.txt
输入:

  • apple
  • car
  • tower

输出:

  • 3 rewot
  • 2 rac
  • 1 elppa

任务要求我使用动态数组来存储这些行,我不能在读取行之前计算文件的行数,如果行数大于动态数组的大小,我应该将其大小加倍。

我已经做了一些工作,但有点混乱,我知道这个网站不是用来完全解决我的任务的,但我会非常感激任何帮助。
(我时间非常有限)

这是我迄今为止所做的:

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

typedef enum Type{
	linenums,
	nolinenums
}Type;

struct str{
	Type type;
	int length;
};

#define BUFFERSIZE 50

int main(int argc, char *argv[])
{
	struct str Data;
	
	if(argc < 3)
	{
		printf("\trev [SHOW LINE NUMBERS] [MAX LINE LENGTH] files...\n");
		exit(1);
	}
	
	if(strcmp(argv[1], "linenums") == 0)
	{
		Data.type = linenums;
	}
	else if(strcmp(argv[1], "nolinenums") == 0)
	{
		Data.type = nolinenums;
	}
	else
	{
		printf("Wrong format!");
		exit(1);
	}
	
	Data.length = atoi(argv[2]);
	
	for(int i=3; i<argc; i++)
	{
		FILE *fpin = fopen(argv[i], "r");
		char buffer[BUFFERSIZE];
		
		int lines = 0;

		if(fpin == NULL)
		{
			fprintf(stderr, "File opening unsuccessful: %s", argv[i]);
			exit(1);
		}
		else
		{	
			char **words = malloc(sizeof(char) * 8);
			for(int i = 0; i < 8; i++)
			{
				words[i] = malloc(sizeof(char*) * 1025);
				if(words[i] == NULL)
				{
					printf("Memory allocation unsuccesful");
					exit(1);
				}
			}

			while(fgets(buffer, BUFFERSIZE, fpin) != NULL)
			{
				buffer[strcspn(buffer, "\n")] = '\0';
				strrev(buffer);
				strcpy(words[lines], buffer);
				lines += 1;
			}
			if(Data.type == 0)
			{
				while(lines>0)
				{
					printf("%d %s\n", lines, words[lines-1]);
					lines -= 1;
				}
			}
			else
			{
				while(lines>0)
				{
					printf("%s\n", words[lines-1]);
					lines -= 1;
				}
			}
			
			printf("\n");
		}
		fclose(fpin);
	}
	
	return 0;
}

我的主要问题是动态数组和遍历argv[]数组,当我必须处理多个文件并且在行数多于已分配的行数时仍然必须进行realloc时仍然存在问题。

英文:

I have a task where I should read a text file line by line, then I should reverse the line (the line contains one string), also at the same time I have to reverse the order of the lines, so the last one should be the first the one before last should be the second and so on and I have to write all these on the standard output.

First I should read an enum from argv[] f which could be "linenums" or "nolinenums", if it is "nolinenums" I have nothing to do, but with "linenums" I have to number the lines backwards. Then an int and the other arguments should be the name of the files.

an example: ./main linenums 5 example.txt
input:

  • apple
  • car
  • tower

output:

  • 3 rewot
  • 2 rac
  • 1 elppa

The task says I have to use dynamic array to store the lines, I can't count the lines of the file before reading the lines, if the amount of the lines is bigger then the size of the dynamic array I should double its size.

well I did something, but it's kind of messy, I know this site is not for making the my task completely, but I would much appreciate it, but any help would be nice.
(I have very limited time also)

This is what I've done so far:

#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &lt;stdlib.h&gt;
typedef enum Type{
linenums,
nolinenums
}Type;
struct str{
Type type;
int length;
};
#define BUFFERSIZE 50
int main(int argc, char *argv[])
{
struct str Data;
if(argc &lt; 3)
{
printf(&quot;\trev [SHOW LINE NUMBERS] [MAX LINE LENGTH] files...\n&quot;);
exit(1);
}
if(strcmp(argv[1], &quot;linenums&quot;) == 0)
{
Data.type = linenums;
}
else if(strcmp(argv[1], &quot;nolinenums&quot;) == 0)
{
Data.type = nolinenums;
}
else
{
printf(&quot;Wrong format!&quot;);
exit(1);
}
Data.length = atoi(argv[2]);
for(int i=3; i&lt;argc; i++)
{
FILE *fpin = fopen(argv[i], &quot;r&quot;);
char buffer[BUFFERSIZE];
int lines = 0;
if(fpin == NULL)
{
fprintf(stderr, &quot;File opening unsuccessful: %s&quot;, argv[i]);
exit(1);
}
else
{	
char **words = malloc(sizeof(char) * 8);
for(int i = 0; i &lt; 8; i++)
{
words[i] = malloc(sizeof(char*) * 1025);
if(words[i] == NULL)
{
printf(&quot;Memory allocation unsuccesful&quot;);
exit(1);
}
}
while(fgets(buffer, BUFFERSIZE, fpin) != NULL)
{
buffer[strcspn(buffer, &quot;\n&quot;)] = &#39;\0&#39;;
strrev(buffer);
strcpy(words[lines], buffer);
lines += 1;
}
if(Data.type == 0)
{
while(lines&gt;0)
{
printf(&quot;%d %s\n&quot;, lines, words[lines-1]);
lines -= 1;
}
}
else
{
while(lines&gt;0)
{
printf(&quot;%s\n&quot;, words[lines-1]);
lines -= 1;
}
}
printf(&quot;\n&quot;);
}
fclose(fpin);
}
return 0;
}

My main problem is the dynamic array and iterating through the argv[] array

thanks to pm100 my output is right with the example, but I still have the problem when I have to work with more than one file and I still have to do the realloc when the number of lines are more than the already allocated ones (I should double it).

答案1

得分: 1

基本问题在于

    words[lines] = buffer;

这并不是复制字符串,而是替换了指向你刚刚分配的内存的 words 数组中的指针。

你需要

    strcpy(words[lines], buffer);
英文:

fundamental problem here

 words[lines] = buffer;

this does not copy the string, instead it replaces the pointer in the words array (that points to memory you just allocated above)

you need

  strcpy(words[lines], buffer);

huangapple
  • 本文由 发表于 2023年1月9日 02:10:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/75050219.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定