如何通过指向另一个指针然后指向此字符串的指针来更改填充此字符串

时间:2016-01-17 23:59:33

标签: c pointers

我不确定我应该怎么做。这是我的代码。 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);
}

编辑:我知道有更好的方法可以做到这一点。我这样做只是为了帮助解释我试图理解的情况,这是如何将指针传递给指向函数的指针来编辑字符串。

3 个答案:

答案 0 :(得分:0)

如果您有char *p1 = &string[0],则只需将p1的值分配给p2char *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以上的分配后,ptr2string都保持相同的值(即 75-char 数组中第一个字符的地址)。

现在,当您将指针作为参数传递给函数时,函数会接收指针的副本,就像函数接收任何其他变量的副本一样。这个很重要。如果已经声明并分配了指针(静态或动态),则只需传递指针的副本,函数仍将接收其值(数组的地址)。在这种情况下,没有必要传递指针地址,(例如char **)传递指针本身(即使作为副本传递)其仍然提供阵列所需的地址

在需要传递指针地址的唯一情况是在指针未分配的情况下(即NULL - 保持无地址),或者指针本身的地址很重要(即将指针传递给链接列表,您打算在其中更改列表中的第一个节点等。)在这些情况下,然后让调用函数保持正确引用新创建的指针或列表的新地址(如果删除/添加新的第一个节点) - 必须将指针的地址传递给函数。在您的情况下,这不是必需的。

事实上,在您的情况下,您传递给readLineptr1ptr2string)并不重要完全相同的值 - 已分配数组的起始地址。您可以使用任何一个读取值,因为您读取的字符将从完全相同的地址开始存储。

考虑到这一点,你可以做类似以下的事情:

#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是指向字符数组中第一个元素的指针。

话虽如此,我不理解ptr1ptr2的角色。如果要读入字符串,可以简单地使用fscanf

char string[80];
FILE * pFile;

pFile = fopen ("myfile.txt","r");
fscanf (pFile, "%s", string);

当然,您需要检查fopenfscanf的返回值。关于C函数readline,它存在于libreadlinelibedit两个位置。如果您正在实施自己的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;
}

这通过指针strreadLine(&str))的地址,指针本身在函数(*arr = "efgh")中更改。