【问题标题】:fprintf output is returning unpredictable resultsfprintf 输出返回不可预测的结果
【发布时间】:2013-05-07 18:37:56
【问题描述】:

我的fprintf() 正在返回不可预测的结果。我认为它返回的是内存地址号,而不是内存地址内的数据。有人可以看看我的代码并检查一下吗?当我在fprintf() 中使用&source 时,我被告知它是未声明的,当我在函数顶部声明它时它不起作用。

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

int MenuLoop = 0;
int MaxPackets = 4;
int currentPackets= 0;
int menu;

/*********************************************************
* Node to represent a Cat which includes a link reference*
* a link list of nodes with a pointer to a Cat Struct    *
* would be better but this is for illustartion only!     *
**********************************************************/
struct Packet {
int Source;
int Destination;
int Type;
int Port;
char *Data;
struct Packet *next; // Link to next Cat
};

typedef struct Packet node; // Removes the need to constantly refer to struct 

/*********************************************************
* Stubs to fully declared functions below                *
**********************************************************/
void outputPackets(node **head);
void push(node **head, node **aPacket);
node* pop(node **head);
void AddPacket();
void AddPacket();
void SavePacket();
void ShowCurrent();
void ExitProgramme();


main() {

do{

Menu();

} while(menu<4);

}


void AddPacket(){

int option;

/*********************************************************
* pointers for the link list and the temporary P to    *
* insert into the list                                   *
**********************************************************/
node *pPacket, *pHead = NULL;

/*********************************************************
* Create a cat and also check the HEAP had room for it   *
**********************************************************/
pPacket = (node *)malloc(sizeof(node));
if (pPacket == NULL)
{
    printf("Error: Out of Memory\n");
    exit(1);
}

currentPackets++;
printf("Enter Source Number between 1-1024:\n");

scanf("%i", &pPacket->Source);
printf("Enter Destination Number between 1-1024:\n");
scanf("%i", &pPacket->Destination);
printf("Enter Type Number between 0-10:\n");
scanf("%i", &pPacket->Type);
printf("Enter Port Number between 1-1024:\n");
scanf("%i", &pPacket->Port);
printf("Enter Data Numberbetween 1-50:\n");
scanf("%s", &pPacket->Data);
printf("Do you want to Enter another Packet?");
pPacket->next = NULL;

/*********************************************************
* Push the Cat onto the selected Link List, the function *
* is written so the program will support multiple link   *
* list if additional 'pHead' pointers are created.       *
* Who says you cannot herd cats!                         *
**********************************************************
* NOTE: The push parameters are using references to the  *
* pointers to get round the pass by value problem caused *
* by the way C handles parameters that need to be        *
* modified                                               *
**********************************************************/

push(&pHead, &pPacket);

pPacket = (node *)malloc(sizeof(node));
if (pPacket == NULL)
{
    printf("Error: Out of Memory\n");
    exit(1);
}

 outputPackets(&pHead);

/*********************************************************
* Display the Link List 'pHead' is passed as a reference *
**********************************************************/


return 0;


do{
    if(currentPackets == MaxPackets);
{
    printf("Packet limit reached please save\n");

}


}while(currentPackets<MaxPackets);

return 0;
}


void outputPackets(node **head)
{

/*********************************************************
* Copy Node pointer so as not to overwrite the pHead     *
* pointer                                                *
**********************************************************/
node *pos = *head;

/*********************************************************
* Walk the list by following the next pointer            *
**********************************************************/
while(pos != NULL) {
    printf("Source: %.4i Destination: %.4i Type: %.4i Port: %.4i \n", pos->Source, pos->Destination, pos->Type, pos->Port);

    pos = pos->next ;
}
printf("End of List\n\n");
}


void push(node **head, node **aPacket)
{
/*********************************************************
* Add the cat to the head of the list (*aCat) allows the *
* dereferencing of the pointer to a pointer              *
**********************************************************/
(*aPacket)->next = *head;
*head = *aPacket;
}

node *pop(node **head)
{
/*********************************************************
* Walk the link list to the last item keeping track of   *
* the previous. when you get to the end move the end     *
* and spit out the last Cat in the list                  *
**********************************************************/
node *curr = *head;
node *pos = NULL;
if (curr == NULL)
  {
    return NULL;
   } else {
    while (curr->next != NULL)
    {
        pos = curr;
        curr = curr->next;
    }
    if (pos != NULL) // If there are more cats move the reference
    {
        pos->next = NULL;
    } else {         // No Cats left then set the header to NULL (Empty list)
        *head = NULL;
    }
}
return curr;

}


void SavePacket(Source, Destination, Type, Port, Data){

FILE *inFile ;
char inFileName[10] = { '\0' } ;

printf("Input file name : ") ;
scanf("%s", inFileName) ;

//Open file
inFile = fopen(inFileName, "w+");
if (!inFile)
{
fprintf(stderr, "Unable to open file %s", &inFile);
exit(0);

}

fprintf(inFile, "Source: %i Destination: %i Type: %i Port: %i Data: %s \n", Source, Destination, Type, Port, Data);
fclose(inFile);

}


void ShowCurrent(){

}

void ExitProgramme(){}

void Menu(){

printf("********Welcome****** \n");
printf("Creator Ben Armstrong.\n\n");
printf("*Please Choose an option*\n");
printf("1. Add a new packet\n");
printf("2. Save current packet to file\n");
printf("3. Show current list of packets\n");
printf("4. Exit\n");

scanf("%i", &menu);

switch(menu)

{
    case 1:
    AddPacket();
    break;

    case 2:
        SavePacket();
    break;

    case 3 :
        ShowCurrent();
    break;

    case 4 :
    ExitProgramme();
    break;

}


}

【问题讨论】:

  • 您在哪一行遇到问题?您的 SavePacket 函数声明甚至无效。您在“无法打开文件”fprintf 中将地址打印为字符串...您的示例代码中只有两个 fprintfs,并且只有一个使用源代码,但是由于您没有在函数中指定变量类型声明,我们不知道它在做什么。
  • 这不算作 SSCCE (Simple, Self-Contained, Complete Example)。请努力将代码减少到最低限度。突出显示导致您出现问题的 fprintf() 呼叫会有所帮助——我在格式化问题时没有注意到这种突出显示。它还有助于“正确”缩进代码(对于 SO,空格不是制表符,每个缩进级别 4 个空格)。
  • 我需要将扫描到 pPacket->source 等的数据传递到我的 savepacket 函数中

标签: c pointers linked-list printf


【解决方案1】:

这是您的问题的一部分...

inFile = fopen(inFileName, "w+");

if (!inFile)
{
    fprintf(stderr, "Unable to open file %s", &inFile);
    exit(0);    
}

我很确定你的意思是......

inFile = fopen(inFileName, "w+");

if (!inFile)
{
    fprintf(stderr, "Unable to open file %s", inFileName );
    exit(0);    
}

还要注意&amp;inFileinFile 变量的地址,而不是存储在FILE 指针中的值。

此外,您声明用于保存数据的函数原型如下...

void SavePacket(Source, Destination, Type, Port, Data)

这表示您正在传递 SourceDestinationTypePortData 参数,但显然您的意思是那些是名称,而不是类型,所以编译器假设它们都是整数。你需要给他们一个类型和一个名字......

void SavePacket( int Source, int Destination, int Type, int Port, char* Data)

现在您可以打印它们了...

fprintf(
    inFile, "Source: %i Destination: %i Type: %i Port: %i Data: %s \n", 
    Source, Destination, Type, Port, Data 
);

但是你有一个更大的混乱,因为你声明 SavePacket() 应该接收参数,但是当你调用它时你没有将参数传递给它......

case 2:
    SavePacket();
break;

应该传入你需要打印的变量。比如……

case 2:
    SavePacket( 
        somePacket->Source, somePacket->Destination, somePacket->Type,
        somePacket->Port, somePacket->Data
    );
    break;

但是,你可以通过这种方式让事情变得更容易......

void SavePacket( struct Packet* packet )
{
    ...

    fprintf(
        inFile, "Source: %i Destination: %i Type: %i Port: %i Data: %s \n", 
        packet->Source, packet->Destination, packet->Type, 
        packet->Port, packet->Data 
    );
}

然后通过传入数据包来调用它...

case 2:
{
    struct Packet somePacket;
    GetPacketDataFromSomewhere( &somePacket );
    SavePacket( &somePacket );
    break;
}

【讨论】:

  • 感谢您的帮助,我已经使用了您上面的建议,但我得到了错误,无效的类型名称'Packet at Void SavePacket(Packet* packet)。您建议的 Packet* 是否将结构传递给我的函数?
  • 是的...抱歉...我在 C++ 模式下...应该是 'struct Packet',而不是 'Packet' -- 进行了相应的编辑。
  • 我能再问一件事吗,我在 SavePacket(somePacket) 中传递了什么;如果我通过 (struct Packet* Packet) 会收到错误消息,抱歉我对 C 编程非常陌生
  • 我假设您正在从某个要写入磁盘的地方获取数据包。我无法回答你得到什么或从哪里得到它的问题。也就是说,请参阅我的编辑,如果这有助于为您澄清...请记住,我知道 GetPacketDataFromSomewhere() 会是什么,而不是说您将指针传递给您的数据包进入它,它用从某个地方得到的东西填充字段的值。
猜你喜欢
  • 2011-11-30
  • 2015-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-25
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
相关资源
最近更新 更多