我不确定我应该怎么做。这是我的代码。 readLine函数从文件中读取行,并通过ptr2将其存储在字符串中。我有一种感觉,我搞乱了星星。有人可以向我解释一下这样做的正确方法。
int main(int argc, char **argv)
{
FILE *fp;
fp = fopen("testFile.txt","r");
if( fp == NULL ){
printf("Error while opening the file.\n");
}
char string[75];
char *ptr1 = &string[0]; //want ptr1 to point to string
char *ptr2 = &ptr1[0]; //want ptr2 to point to ptr1
readLine(fp,**ptr2); //want to send ptr2 pointer so that function read the file and add it to string can be edited through the pointer.
printf("%s", **string);
fclose(fp);
return 0;
}
readLine(FILE *fp, char **string){
fgets(**string, 75, fp);
}
编辑:我知道有更好的方法可以做到这一点。我这样做只是为了帮助解释我试图理解的情况,这是如何将指针传递给指向函数的指针来编辑字符串。
答案 0 :(得分:0)
如果您有char *p1 = &string[0]
,则只需将p1
的值分配给p2
:char *p2 = p1
。
我认为星号让你感到困惑。如果你在变量声明中有一个星号,如下所示:char *p2
,这意味着变量p2
是一个指针,但当你在另一个地方有星号时,例如*p2 = 'c'
,你就是取消引用指针,即将'c'
的值直接保存到p2
指向的内存位置。
所以,这是你的代码,修复:
int main(int argc, char **argv)
{
FILE *fp;
fp = fopen("testFile.txt","r");
if( fp == NULL ){
printf("Error while opening the file.\n");
}
char string[75];
char *ptr1 = string;
char *ptr2 = ptr1;
readLine(fp, ptr2);
printf("%s", **pbuff); // I don't know what pbuff is
fclose(fp);
return 0;
}
readLine(FILE *fp, char *string){
fgets(string, 75, fp);
}
请记住,我没有编译这个,因为我现在无法使用我姐姐的电脑而且她不是程序员。 :)
答案 1 :(得分:0)
您遇到的困难和问题似乎源于您对指针的不熟悉,以及它们如何作为参数传递给函数。声明字符数组时,例如char string[75];
string
保存的值是静态声明的 75-char 数组中第一个字符(或起始内存地址)的地址。 (它本身是指针)。
当你声明另一个指向数组的指针时,你需要做的就是将string
(一个指向string[0]
地址的指针)所持有的值赋给任何创建的新指针。 e.g:
char *ptr1 = string;
char *ptr2 = ptr1;
与声明两个指针然后将它们设置为string
完全相同,例如:
char *ptr1, *ptr2;
ptr1 = ptr2 = string;
当您处理指针时,它们只不过是一个变量,它将地址保存为其他值作为其值。因此,在ptr1
以上的分配后,ptr2
和string
都保持相同的值(即 75-char 数组中第一个字符的地址)。
现在,当您将指针作为参数传递给函数时,函数会接收指针的副本,就像函数接收任何其他变量的副本一样。这个很重要。如果已经声明并分配了指针(静态或动态),则只需传递指针的副本,函数仍将接收其值(数组的地址)。在这种情况下,没有必要传递指针的地址,(例如char **
)传递指针本身(即使作为副本传递)其值仍然提供阵列所需的地址。
在需要传递指针地址的唯一情况是在指针未分配的情况下(即NULL
- 保持无地址),或者指针本身的地址很重要(即将指针传递给链接列表,您打算在其中更改列表中的第一个节点等。)在这些情况下,然后让调用函数保持正确引用新创建的指针或列表的新地址(如果删除/添加新的第一个节点) - 必须将指针的地址传递给函数。在您的情况下,这不是必需的。
事实上,在您的情况下,您传递给readLine
(ptr1
,ptr2
或string
)并不重要完全相同的值 - 已分配数组的起始地址。您可以使用任何一个读取值,因为您读取的字符将从完全相同的地址开始存储。
考虑到这一点,你可以做类似以下的事情:
#include <stdio.h>
char *readLine (FILE *fp, char *string);
int main (int argc, char **argv) {
char string[75] = {0};
FILE *fp = NULL;
char *fn = argc > 1 ? argv[1] : "testFile.txt"; /* filename */
char *ptr1, *ptr2;
ptr1 = ptr2 = string;
if (!(fp = fopen (fn, "r"))) { /* validate file open */
fprintf (stderr, "error: file open failed '%s'.\n", fn);
return 1;
}
if (readLine (fp, ptr2))
printf ("%s\n", ptr1); /* any reference to string will work */
else
fprintf (stderr, "error: readLine failure.\n");
fclose(fp);
return 0;
}
char *readLine (FILE *fp, char *string)
{
return fgets (string, 75, fp);
}
示例输入文件
$ cat ../dat/captnjack.txt
This is a tale
Of Captain Jack Sparrow
A Pirate So Brave
On the Seven Seas.
使用/输出强>
$ ./bin/readln ../dat/captnjack.txt
This is a tale
答案 2 :(得分:-1)
宣布:
char string[80];
string
是指向字符数组中第一个元素的指针。
话虽如此,我不理解ptr1
和ptr2
的角色。如果要读入字符串,可以简单地使用fscanf
。
char string[80];
FILE * pFile;
pFile = fopen ("myfile.txt","r");
fscanf (pFile, "%s", string);
当然,您需要检查fopen
和fscanf
的返回值。关于C函数readline
,它存在于libreadline
和libedit
两个位置。如果您正在实施自己的readLine
,它可能也会遇到问题。
附录:如果要修改函数内的字符串,请说readLine
void readLine(char **arr){
*arr = "efgh";
}
int main(int argc, const char** argv){
char *str = "abcd";
printf("%s\n",str);
readLine(&str);
printf("%s\n",str);
return 0;
}
这通过指针str
(readLine(&str)
)的地址,指针本身在函数(*arr = "efgh"
)中更改。