我正在尝试编写一个从文件中获取单词的程序,并将它们放在动态数组中。但是,当我尝试运行我的代码时,程序将其复制除了空格。我该如何解决这个问题?
这是一个测试吗?
但我得到以下内容:
Thisisatestdoesitwork?
char** getWords(char* filename, int* pn){
char** tmp = (char**)malloc( 1000*sizeof(char));
int *temp=(int*)malloc(1000*sizeof(int);
int c;
int counter = 0;
FILE* fileInput = fopen(filename, "r");
if(fileInput == NULL){
return tmp; // return if file open fails
}
while((c=fgetc(fileInput)) != EOF){
result = fscanf(fileInput, "%c", &c); //try to read a character
if(isalpha(c)){ //chararect alphabetical
tmp[counter] = c; // safe int to array
counter ++;
printf("%c", c); fflush(stdout);
}
else{ // if read not succesfull
fscanf(fileInput, ""); // needs to scan anything not a character
}
if(counter > 100){ // to not exceed the array
break;
}
if(feof(fileInput)){ // to check if at the end of the file
break;
}
}
fclose(fileInput); // closing file
*pn = counter;
return tmp;}
我的主要功能:
int main(int argc, char* argv[]){
int n;
char** a = getWords("opdracht_4_5.c", &n);
if (a != NULL){
puts("gevonden woorden:");
for (int i = 0;i < n; i++){
printf("%3d %s\n",i,a[i]);
}
for (int i = 0;i < n; i++){
free(a);
}
free(a);
}
return (EXIT_SUCCESS);
}
答案 0 :(得分:1)
您的代码存在很多问题。这是一个开始:
fopen()
的返回值。malloc()
的返回值。fgetc()
的返回值分配给char
类型的变量。简单char
与signed char
或unsigned char
兼容。为了区分字符和EOF
(负数),fgetc()
函数返回转换为 unsigned char
(或EOF)的字符。您需要测试EOF
然后将值转换为普通char
。is...()
函数需要int
参数,其值在 unsigned char
或EOF
的范围内。如果您使用普通char
,则必须先将其转换为unsigned char
,否则您可以将fgetc()
的返回值直接传递给isalpha()
。char
数组(temp
)附加到未初始化的char
数组(s
),并且您不会测试是否有足够的数据char
目标数组中的房间。这个被打破的原因比我想要列举的更多。char
的1000个指针的数组分配内存,但您永远不会为s
指针本身分配内存。*tmp
)附加到未初始化的指针(strlen()
)。答案 1 :(得分:0)
这个答案尚不完整
请允许我在评论之前完成此操作 - 谢谢
如果您的代码出现问题,有很多问题,我不会为您清理。不过,我想就你的程序应该如何编码提供一些提示:
您的主要目标是读取文件并在数组中逐字加载内容。
排序是一种不正确的用法,因为这意味着您希望在将其加载到数组后按字母顺序或以其他顺序对它们进行排序。
好的,首先,让我们弄清楚我们计划的整体运作。我们称之为我们的程序小猫,因为它不像猫那么强大。
要运行我们的程序,我们假设我们在命令行中为它提供了我们想要读取的文件名,如下所示:
$ ./kitten somefile.txt
并期望输出为:
word1
word2
word3
.
.
.
wordN
Total words: N
所以,让我们开始吧,首先我们确保用户指定文件名:
#include <stdio.h>
int usage(const char *progname);
int main(int argc, char *argv[])
{
if (argc < 2) {
usage(argv[0]);
return -1;
}
return 0;
}
int usage(const char *progname)
{
fprintf(stderr, "Usage is:\n\t%s filename\n", progname);
}
现在我们知道我们的程序可以获取文件名,让我们尝试打开文本文件,如果有问题,我们使用perror来显示错误并退出程序,否则我们准备使用该文件:
#include <stdio.h>
#include <errno.h>
int usage(const char *progname);
int main(int argc, char *argv[])
{
FILE *fp;
if (argc < 2) {
usage(argv[0]);
return -1;
}
fp = fopen(argv[1], "r");
if (!fp) {
perror(argv[1]); /* display system error, with the filename */
return -1;
}
/* TODO: file manipulation goes here */
fclose(fp); /* close the file */
return 0;
}
int usage(const char *progname)
{
fprintf(stderr, "Usage is:\n\t%s filename\n", progname);
}
现在在C中,每个函数应该只执行一个任务。这项任务应该让人有意义。例如,如果该函数应该将单词读入数组,那就应该这样做,它不应该打开文件或关闭文件,这就是为什么上面的代码不会像你那样创建打开文件的函数没有。您的函数应该将FILE *
作为要读取的文件。
因为我们使用FILE *
作为输入,所以我们将使用f
启动函数名以保持stdio约定。理想情况下,该函数应该使用指向char *
(字符串)的指针来存储单词。
#include <stdio.h>
#include <errno.h>
int usage(const char *progname);
size_t fload(FILE *fp, char **wordlist_p);
int main(int argc, char *argv[])
{
FILE *fp;
if (argc < 2) {
usage(argv[0]);
return -1;
}
fp = fopen(argv[1], "r");
if (!fp) {
perror(argv[1]); /* display system error, with the filename */
return -1;
}
if(fload(fp, wordlist_p) < 0) {
fprintf(stderr, "Something went wrong\n")
}
fclose(fp); /* close the file */
return 0;
}
int usage(const char *progname)
{
fprintf(stderr, "Usage is:\n\t%s filename\n", progname);
}
size_t fload(FILE *fp, char **wordlist_p)
{
size_t rv = -1; /* return value */
return rv;
}
现在我们遇到了一个概念问题。我们如何为wordlist_p
分配内存?我的意思是我们不知道文件有多大,我们也不知道文件中最大的单词有多大。
让我们首先尝试以简单的方式思考它:
Point to the beginning of the `wordlist_p` with a `tail_pointer`
Read the file line by line, (we assume no hyphenation)
For each line split the line up along white spaces,
Allocate space for the number of words in the `wordlist_p` array
For each word in the split line
Allocate space for the word itself
Save the pointer to the word at the tail_pointer
Advance wordlist_p tail_pointer
Next word
Next Line
让我们看看上面这些步骤fload
函数的外观,
答案 2 :(得分:0)
这将读取文件,将每个单词放在一个数组中
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
char** getWords(char* filename, int* pn){
char input[100]; // array to hold each word
char** tmp; // double pointer
int counter = 0;
int words = 0;
int c;
tmp = malloc( (*pn)*sizeof(char*)); // allocate pointers for number of words
if ( tmp == NULL) {
printf ( "malloc failed\n");
exit (1);
}
FILE* fileInput = fopen(filename, "r");
if(fileInput == NULL){
printf ( "file open failed\n");
*pn = 0; // no words entered
return tmp; // return if file open fails
}
while(( c = fgetc(fileInput)) != EOF){
if( isalnum(c)){ // is alpha or number
input[counter] = c; // save to array
input[counter + 1] = '\0'; // save a \0 to the end to make a string
counter ++;
}
else{ // not alpha or number
if ( counter > 0) { // if there are characters, save the word
tmp[words] = malloc ( strlen ( input) + 1); // memory for this word
strcpy ( tmp[words], input); // copy the word to the array
words++;
counter = 0;
if ( words >= *pn) { // got all the words wanted
break;
}
}
}
if(counter > 98){ // too many characters for input, start a new word
tmp[words] = malloc ( strlen ( input) + 1);
strcpy ( tmp[words], input);
words++;
counter = 0;
if ( words >= *pn) {
break;
}
}
}
fclose(fileInput); // closing file
*pn = words; // save number of words
return tmp;
}
int main(int argc, char* argv[]){
int n;
int i;
printf ( "enter the number of words to obtain\n");
scanf ( "%d", &n);
char** a = getWords("opdracht_4_5.c", &n);
if (a != NULL){
puts("gevonden woorden:");
for ( i = 0;i < n; i++){
printf("%3d %s\n",i,a[i]);
}
for ( i = 0;i < n; i++){
free(a[i]); // free each word
}
free(a); // free the pointer to the words
}
return (EXIT_SUCCESS);
}
我使用的输入文件将这些作为前两行
#include<stdio.h>
#include<string.h>
我得到了这个输出:
输入要获取的字数
6
gevonden woorden:
0包括
1 stdio
2小时
3包括
4弦
5小时