天道酬勤,学无止境

fwrite in C giving different values in output files

why are the output files different when I use fwrite in another function VERSUS fwrite in the same function?

output1.txt contains garbage value like Ê, which is NOT correct

output2.txt contains "b", which is correct

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

void writeData(char *buf, char *path) {
    FILE *fp1;
    fp1 = fopen(path, "a");
    fwrite(&buf, sizeof(char), strlen(buf), fp1);
}

int main () {


    char buf[2] = "a";
    char buf2[3] = "yb";
    char file1_path[12] = "output1.txt";
    char file2_path[12] = "output2.txt";
    memset(buf, 0, sizeof(buf));
    memcpy(buf, &buf2[1], strlen(buf2));
    printf("%s\n", buf);

    writeData(buf, file1_path);

    FILE *fp2;
    fp2 = fopen(file2_path, "a");
    fwrite(&buf, sizeof(char), strlen(buf), fp2);

   return(0);
}
标签

评论

In the writeData function, in your call to fwrite:

fwrite(&buf, sizeof(char), strlen(buf), fp1);

the variable buf is a pointer to the first character in the string to write. It's of typechar *. However the expression &buf is a pointer to the variable buf, its type is char **. It's not the same data.


It works if buf is an array because both then buf (which is really &buf[0]) and &buf points to the same location. They are still different types though.

For example with

char buf[2];

then buf decays to a pointer to the arrays first element (i.e. &buf[0]) and is of type char *. The expression &buf is a pointer to the array and is of type char (*)[2].

Somewhat graphically

+--------+--------+
| buf[0] | buf[1] |
+--------+--------+
^
|
&buf[0]
|
&buf

Two pointers to the same location, but different types and different semantic meanings.

In function writeData change

fwrite(&buf, sizeof(char), strlen(buf), fp1);

to

fwrite(buf, sizeof(char), strlen(buf), fp1);

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 二进制零和ASCII字符零之间的差异(Difference between binary zeros and ASCII character zero)
    问题 gcc (GCC) 4.8.1 c89 你好, 我正在读一本有关指针的书。 并使用以下代码作为示例: memset(buffer, 0, sizeof buffer); 将填充缓冲区将二进制零而不是字符零。 我只是想知道二进制和字符零之间有什么区别。 我以为是同一回事。 我知道文本数据是人类可读的字符,而二进制数据是不可打印的字符。 如果我错了,请纠正我。 什么是二进制数据的好例子? 例如,如果要处理字符串(文本数据),则应使用fprintf 。 如果使用二进制数据,则应使用fwrite 。 如果要将数据写入文件。 非常感谢您的任何建议, 回答1 简单的答案是,字符'0'在二进制数据中由ASCII数字48表示。这意味着,当您需要字符'0' ,文件中实际上包含以下位: 00110000 。 类似地,可打印字符'1'的十进制值为49,由字节00110001表示。 ( 'A'为65,表示为01000001 ,而'a'为97,表示为01100001 ) 如果要在字符串'\0'的末尾使用空终止符,则实际上具有十进制的0值,因此将是全零的字节: 00000000 。 这确实是一个0值。 对于编译器,两者之间没有区别 memset(buffer, 0, sizeof buffer); 和 memset(buffer, '\0', sizeof buffer); 唯一的区别是语义上的差异。
  • 如何将结构保存在文件中?C lang(how can I save struct in file … C lang)
    问题 我想将结构保存在文件中。 我想实现一个使这项工作有效的功能。 我尝试了这段代码,但是没有用。 struct utilisateur // enregestrement pour sauvegarder les details de l utilisateur { char nom[20]; char prenom[20]; int place; char depart[20]; char arrive[20]; char sexe; int nwagon; }; struct utilisateur utilis; struct utilisateur *Table[48]; void crea_fich(struct utilisateur *Tutilis) // creation un fichier, vous introduiez le nom, et le sotcker par enreg { FILE *f; if (f!==0) { printf("error in the name of file \n"); exit(1); } if (f=fopen(futilis,"w")==Null){ fprint("We can't creat file \n"); exit(1); } else{ f=fopen("futilis.dat","wb")
  • 读取文件并填充结构(Reading file and populating struct)
    问题 我有一个具有以下定义的结构: typedef struct myStruct{ int a; char* c; int f; } OBJECT; 我能够填充此对象并将其写入文件。 但是我无法读取其中的char * c值...尝试读取它时,它给我一个分段错误错误。 我的代码有什么问题吗: //writensave.c #include "mystruct.h" #include <stdio.h> #include <string.h> #define p(x) printf(x) int main() { p("Creating file to write...\n"); FILE* file = fopen("struct.dat", "w"); if(file == NULL) { printf("Error opening file\n"); return -1; } p("creating structure\n"); OBJECT* myObj = (OBJECT*)malloc(sizeof(OBJECT)); myObj->a = 20; myObj->f = 45; myObj->c = (char*)calloc(30, sizeof(char)); strcpy(myObj->c, "This is a test"); p("Writing object
  • 如何使用 fread 从文件中读取特定数据?(How to read particular data from file using fread?)
    问题 以下代码使用 fwrite 将学生的数据写入文件并使用 fread 读取数据: struct record { char name[20]; int roll; float marks; }student; #include<stdio.h> void main() { int i; FILE *fp; fp=fopen("1.txt","wb"); //opening file in wb to write into file if(fp==NULL) //check if can be open { printf("\nERROR IN OPENING FILE"); exit(1); } for(i=0;i<2;i++) { printf("ENTER NAME, ROLL_ NO AND MARKS OF STUDENT\n"); scanf("%s %d %f",student.name,&student.roll,&student.marks); fwrite(&student,sizeof(student),1,fp); //writing into file } fclose(fp); fp=fopen("1.txt","rb"); //opening file in rb mode to read particular data if(fp==NULL) /
  • 在c语言中,putw和getw函数的用途是什么?(What is the use of `putw` and `getw` function in c?)
    问题 我想知道putw()和getw()函数的getw() 。 据我所知,它们像putc和getc一样用于文件读写,但是它们仅处理整数。 但是,当我使用它们写整数时,它只是在文件中写了不同的符号(就像我使用putw()将65写到文件中putw() 。它在文件中写了A )。 为什么要采用ASCII值? 我正在使用代码块13.12。 代码: #include <stdio.h> int main() { FILE *fp; int num; fp = fopen("file.txt", "w"); printf("Enter any number:\n"); scanf("%d", &num); putw(num, fp); fclose(fp); printf("%d\n", num); return 0; } 回答1 让我们阅读一下getw()和putw()函数的点对点解释。 getw()和putw()与FILE处理有关。 putw()用于在文件(文本文件)上写入整数数据。 getw()用于从文件读取整数数据。 getw()和putw()与getc()和putc()类似。 唯一的区别是getw()和putw()特别用于读取和写入整数数据。 int putw(integer, FILE*); 函数的返回类型为整数。 有两个参数,第一个为“整数”,告诉您要在文件上写入的整数
  • Linux文件IO--文件描述符/重定向
    Linux文件IO--文件描述符/重定向 1.基础IO1.1C语言文件IO1.2Linux系统文件IO1.3Linux 系统调用与C库函数对比打开文件关闭文件写文件读文件fseek&lseek 2.文件描述符2.1基本概念2.2struct file(file结构体)2.3struct files_struct2.4文件流指针与文件描述符2.5文件描述符的分配规则 3.重定向3.1基本概念3.2在Shell中的使用输出重定向追加重定向&清空重定向 错误重定向输入重定向 4. dup2()系统调用 1.基础IO 1.1C语言文件IO 给一个testio.txt写入Hello World:通过操作文件流指针完成。 #include<stdio.h> #include<string.h> int main(){ FILE* fp = fopen("testio.txt", "w+"); if(fp == NULL){ printf("打开失败\n"); } const char* str = "Hello World!\n"; int count = 6; int len = strlen(str); while(count--){ fwrite(str, len, 1, fp); } fseek(fp, 0 , 0); char buf[1024] = { 0 }; count = 6
  • fwrite和write之间的主要区别是什么?(what are the main differences between fwrite and write?)
    问题 我目前正在用C编写一个回调函数: static size_t writedata(void *ptr, size_t size, size_t nmemb, void *stream){ size_t written = fwrite(ptr, size, nmemb, (FILE)*stream); return written; } 该函数将在另一个函数中使用,该函数执行HTTP请求,检索请求,并将其写入本地计算机。 该writedata函数将在后面的部分中使用。 整个操作必须是multithreaded ,因此我对write和write之间是fwrite 。 有人可以帮我概述一下C write()和fwrite()之间的区别,以便我可以选择最适合我的问题的那个吗? 回答1 fwrite写入FILE* ,即(可能)缓冲的stdio流。 它由ISO C标准指定。 另外,在POSIX系统上,fwrite在某种程度上是线程安全的。 write是在POSIX标准中描述的基于文件描述符的低级API。 它不知道缓冲。 如果要在FILE*上使用它,请使用fileno获取其文件描述符,但是在尝试进行write之前,请确保手动锁定并刷新流。 除非您知道自己在做什么,否则请使用fwrite 。 回答2 一个非常明显的区别是write是原子的,而fwrite不是。 https:/
  • fwrite()-大小和数量对性能的影响(fwrite() - effect of size and count on performance)
    问题 关于fwrite()中两个参数“大小”和“计数”的目的,似乎有很多困惑。 我正在尝试找出哪个会更快- fwrite(source, 1, 50000, destination); 或者 fwrite(source, 50000, 1, destination); 这是我代码中的重要决定,因为此命令将执行数百万次。 现在,我可以跳到测试并使用可以提供更好结果的测试,但是问题是该代码旨在用于许多平台。 所以, 如何获得跨平台哪个更好的明确答案? fwrite()的实现逻辑会因平台而异吗? 我意识到也有类似的问题(fread / fwrite以大小和计数为参数的基本原理是什么?fwrite和write size的性能),但确实理解这是关于同一问题的不同问题。 在这种情况下,类似问题的答案是不够的。 回答1 性能不应依赖于任何一种方式,因为实现fwrite的任何人都将乘以大小和计数来确定要执行多少I / O。 FreeBSD的fwrite.c的libc实现示例了这一点,该实现全部读取(包括了被删除的指令): /* * Write `count' objects (each size `size') from memory to the given file. * Return the number of whole objects written. */ size_t fwrite
  • Linux 基础IO(系统调用/文件描述符/重定向)
    目录 Linux 系统 . 文件IO Linux 系统调用与C库函数对比记忆 fopen & open fclose & close fwrite & write fread & read fleek & leek stdin & stdout & strerr 文件描述符fd struct file(file结构体) struct files_struct 0 & 1 & 2 文件流指针与文件描述符 文件描述符的分配规则 重定向 在Shell中的使用 输出重定向(常用) >>(追加重定向) & >(清空重定向) 输入重定向 dup2()系统调用 引言 Linux 的基础IO接口和C语言中IO相关的库函数用法相似, 先简单回顾一下C中是怎样操作的. #include<stdio.h> #include<string.h> int main(){ FILE* fp = fopen("myfile.txt", "w+"); if(fp == NULL){ printf("打开失败\n"); } const char* str = "hello world!\n"; int count = 5; int len = strlen(str); while(count--){ fwrite(str, len, 1, fp); } fseek(fp, 0 , 0); char buf[1024
  • 为什么 fwrite() 在 Mac OS X 上不使用 C 中的“wb”编写二进制文件?(Why doesn't fwrite() write a Binary File using “wb”, in C, on Mac OS X?)
    问题 为了学习 C 并理解二进制文件和文本文件之间的区别,我试图将一个字符串写入文件作为两种文件类型,如下所示: char * string = "I am a string!"; FILE * filePtrA = fopen("/output.txt", "wt"); fwrite(string, strlen(string), 1, filePtrA); FILE * filePtrB = fopen("/output.bin", "wb"); fwrite(string, strlen(string), 1, filePtrB); fclose(filePtrA); fclose(filePtrB); 然而, "wt"和"wb"都写为文本文件,其中"wb"应该写为二进制文件。 对于这两个文件,十六进制看起来像这样: 49 20 61 6D 20 61 20 73 74 72 69 6E 67 21 为什么会发生这种情况,我如何将某些内容写为二进制文件? 我已经读到操作系统(Mac OS X 10.6 - GCC 4.2)可能无法区分二进制文件和文本文件,尽管我仍然不明白为什么十六进制编辑器不会检测到任何差异。 回答1 所有文件都是二进制文件。 fopen上下文中“文本文件”和“二进制文件”之间的区别在于,标准库在文本模式下可能会使用过滤器来读取和写入文件。 在二进制模式下
  • Linux基础IO-文件描述符&重定向&文件系统的理解&动静态库
    C文件接口 首先我们需要理解C文件接口中的几个函数fwrite函数、fread函数 对文件格式化读写函数fprintf与fscanf而言,尽管它可以从磁盘文件中读写任何类型的文件,即读写的文件类型可以是文本文件、二进制文件,也可以是其他形式的文件。但是,对二进制文件的读写来说,考虑到文件的读写效率等原因,还是建议尽量使用 fread 和 fwrite 函数进行读写操作。 头文件:#include<stdio.h> 原型:size_t fread(void *buf, size_t size, size_t count, FILE *fp); size_t fwrite(const void * buf, size_t size, size_t count, FILE *fp); 在上面fread和fwrite函数的原型中: 参数size是指单个元素的大小(其单位是字节而不是位,例如,读取一个int型数据就是4字节);参数count支出要读或写的元素个数,这些元素在buf所指的内存空间中连续存放,共占“size*count”个字节。 即 fread 函数从文件 fp 中读出“size*count”个字节保存到 buf 中,而 fwrite 把 buf 中的“size*count”个字节写到文件 fp 中。最后,函数 fread 和 fwrite 的返回值为读或写的记录数
  • Why doesn't fwrite() write a Binary File using “wb”, in C, on Mac OS X?
    For the sake of learning C and understanding the difference between Binary Files and Text Files, I'm attempting to write a string to file as both file types like so: char * string = "I am a string!"; FILE * filePtrA = fopen("/output.txt", "wt"); fwrite(string, strlen(string), 1, filePtrA); FILE * filePtrB = fopen("/output.bin", "wb"); fwrite(string, strlen(string), 1, filePtrB); fclose(filePtrA); fclose(filePtrB); However both "wt" and "wb" are writing as a Text File, where "wb" should be writing as a Binary File. Hex appears like so for both files: 49 20 61 6D 20 61 20 73 74 72 69 6E 67 21
  • interactive control of a program using php
    I would like to run a C program on a remote computer using php. The final goal is to control the program using a web browser on a phone or any other computer. My C program is acquiring data from different sensors during a few tens of minutes. It runs from command line in linux and I can turn it off by pressing 'q' key on the computer keyboard. The main thread is something like this : int main(){ printf("Program is running... Press 'q' <enter> to quit\n"); fflush(stdout); //create one thread per sensor while (getchar() != 'q'){ } //ask the threads to terminate return(0); } Each thread perform
  • 将位数据输出到二进制文件 C++(Outputting bit data to binary file C++)
    问题 我正在编写一个压缩程序,需要使用 C++ 将位数据写入二进制文件。 如果有人可以就 write 语句或提供建议的网站提供建议,我将不胜感激。 如果这是一个简单或令人困惑的问题,我很抱歉,我正在努力在网上找到答案。 回答1 将位收集成完整字节,例如无符号字符或 std::bitset(其中位集大小是 CHAR_BIT 的倍数),然后一次写入整个字节。 计算机“处理位”,但可用的抽象(尤其是 IO)是您作为程序员处理单个字节。 按位操作可用于切换特定位,但您始终处理字节大小的对象。 在输出结束时,如果您没有整个字节,则需要决定如何存储它。 iostreams 和 stdio 都可以分别使用 ostream::write 和 fwrite 写入未格式化的数据。 代替单个字符或位集<8>(8 是 CHAR_BIT 的最常见值),您可以考虑使用更大的块大小,例如 4-32 个或更多字符的数组或等效大小的位集。 回答2 对于编写二进制文件,我发现最有用的技巧是将所有二进制文件作为单个数组存储在内存中,然后将其全部移至硬盘驱动器。 一次只做一点,一次做一个字节,或一次做一个 unsigned long long 并不像将所有数据存储在一个数组中并使用一个“fwrite()”实例将其存储到硬盘。 size_t fwrite ( const void * ptr, size_t size
  • fwrite是否缓冲输出?(Does fwrite buffer the output?)
    问题 在C ++中,有一个std :: fwrite()将缓冲区写入磁盘上的文件。 您能告诉我该fwrite实现中是否有任何缓冲区? 即,如果我多次调用fwrite()(比如说10次),它实际上是否在10次不同的时间内调用文件I / O? 我要在Ubuntu 10.04环境中使用。 回答1 是的,它是缓冲的。 缓冲区的大小由BUFSIZ定义。 (感谢@ladenedge。)十个足够大的操作将导致十个系统调用。 您还可以使用 std::setbuf 和 std::setvbuf 设置自己的缓冲区。 cstdio中的函数继承自 C。C++ 中的首选接口是fstream和filebuf 。 回答2 这取决于。 在大多数平台上,文件 IO 被缓存,因此存在fflush()调用以将缓存的数据写入磁盘 - 在这方面,您的第一个问题的答案(通常)是“是”,而您的第二个“否”。 也就是说,对于任何特定平台的任何想象都不能保证是那样的——通常,标准只指定这些功能的接口,而不是它们的实现。 此外,如果缓存变“满”,调用fwrite()很可能会导致隐式刷新,在这种情况下,调用fwrite()实际上可能会触发文件 IO - 特别是在调用具有大量数据的fwrite()时。 回答3 FILE* I/O 可以缓冲,但不是必须的(每个流可以不同)。 此外,有多种方法可以进行缓冲(完全缓冲
  • 为什么 fwrite libc 函数比 syscall write 函数快?(Why the fwrite libc function is faster than the syscall write function?)
    问题 在提供读取随机生成的输入文件并将其读取的相同字符串回显到输出的相同程序之后。 唯一的区别是,一方面我提供来自 linux 系统调用的读写方法,另一方面我使用 fread/fwrite。 使用大小为 10Mb 的输入为我的应用程序计时并将其回显到 /dev/null,并确保文件没有被缓存,我发现当使用非常小的缓冲区(1 个字节)时,libc 的 fwrite 速度更快案件)。 这是我使用 fwrite 时的输出: real 0m0.948s user 0m0.780s sys 0m0.012s 并使用系统调用写入: real 0m8.607s user 0m0.972s sys 0m7.624s 我能想到的唯一可能性是内部 libc 已经在缓冲我的输入......不幸的是我在网上找不到那么多信息,所以也许这里的大师可以帮助我。 回答1 使用大小为 10Mb 的输入为我的应用程序计时并将其回显到 /dev/null,并确保文件未缓存,我发现当使用非常小的缓冲区(1 个字节)时,libc 的 frwite 速度更快案件)。 fwrite适用于缓冲的流。 因此,许多小缓冲区会更快,因为它不会运行昂贵的系统调用,直到缓冲区填满(或者您刷新它或关闭流)。 另一方面,发送到write小缓冲区将为每个缓冲区运行一个代价高昂的系统调用——这就是你失去速度的地方。 使用 1024
  • 使用C减少Wav音频文件的音量(Reduce the volume of a Wav audio file using C)
    问题 我正在编写一个用于编辑Wav音频文件的C程序。 我已将所有文件数据加载到无符号整数值(UINT16_T)的数组中。 现在,我想减少文件的数量。 我认为减少单个值的值(一定百分比)就足够了。 但是,如果这样做,我会获得带有噪音的音频文件(我想我知道这被称为“静态”或“点击噪音”) 为什么? 哪个是正确的程序? 谢谢你! 这是受影响的代码: FILE* fp; FILE* fp2; /*Size of my file*/ #define BUFFER_SIZE 28242852 /*Array with file data*/ unsigned char *buffer; /*Array used for converting two bytes in an unsigned int*/ unsigned char uintBytes[2]; /*The unsigned int obtained*/ uint16_t * conv; /*The new value calculated*/ uint16_t nuovoValore; /*Array used for the reverse conversion, form UINT to bytes*/ unsigned char* nuovoValArray; for(i=44; i<BUFFER_SIZE;i++){ if
  • 我的recover.c代码可以正确恢复jpeg,但没有通过cs50检查[关闭](My code for recover.c recovers jpegs correctly but does not pass cs50 check [closed])
    问题 关闭。 此问题不符合 Stack Overflow 准则。 它目前不接受答案。 想改善这个问题吗? 更新问题,使其成为 Stack Overflow 的主题。 4年前关闭。 改进这个问题 这是代码。 我是 C 语言的初学者,因此任何缩短我的代码的建议将不胜感激。 我检查了所有 50 张图像,它们看起来很完美,但代码没有通过 cs50 检查。 int main(void) { FILE* source = fopen("card.raw", "r"); uint8_t jpg[512]; int direct = 0; int jpgcounter = 0; uint8_t checkjpg[4]; FILE* outputfile ; char filename[7] ; while(feof(source) == 0) { fread(jpg,512,1,source); for (int i = 0 ; i < 4 ; i++) { checkjpg[i] = jpg[i]; } if( checkjpg[0] == 0xff && checkjpg[1] == 0xd8 && checkjpg[2] == 0xff && checkjpg[3] >= 0xe0 && checkjpg[3] <= 0xef ) { if ( direct == 0 ) { sprintf
  • 使用 fwrite 将数据从链表写入二进制文件。(Writing data from a linked list to a binary file using fwrite.)
    问题 我不知道如何处理这个任务。 我特别要使用fwrite,但我的问题是我不知道如何将不同的文件类型(char [],int,double)写入二进制文件的一行中,递增它,然后写入下一批数据从链表递增它..... 等等。 下面的代码将数据从链表 (Data) 写入文本文件,转到下一行并重复该过程,直到将列表的最后一个元素写入文本文件。 我需要编写一个具有相同原理的函数,但使用 fwrite 将链接列表中的数据写入二进制文件。 有什么想法吗? void WriteTextFile(ListDataType *Data, int numEl) { FILE *textfile; char name[50]; printf("\n\nWhat would you like to call the text file in which the data will be stored?\nNB remember to add \".txt\" after your chosen name!!!\nENTER NAME NOW>>"); scanf("%s", name); textfile = fopen(name, "w+"); do { fprintf(textfile, "%s %d %d %.2lf %.2lf %.2lf %.2lf\n", Data->component.name
  • 将原始结构内容(字节)写入 C 中的文件。对写入的实际大小感到困惑(Write raw struct contents (bytes) to a file in C. Confused about actual size written)
    问题 基本问题,但我希望这个结构占用 13 个字节的空间(1 个用于 char,12 个用于 3 个无符号整数)。 相反, sizeof(ESPR_REL_HEADER)给了我 16 个字节。 typedef struct { unsigned char version; unsigned int root_node_num; unsigned int node_size; unsigned int node_count; } ESPR_REL_HEADER; 我想要做的是用一些值初始化这个结构并将它包含的数据(原始字节)写入文件的开头,这样当我打开这个文件时,我以后就可以重建这个结构并获得一些元数据有关文件其余部分包含的内容的数据。 我正在初始化结构并将其写入文件,如下所示: int esprime_write_btree_header(FILE * fp, unsigned int node_size) { ESPR_REL_HEADER header = { .version = 1, .root_node_num = 0, .node_size = node_size, .node_count = 1 }; return fwrite(&header, sizeof(ESPR_REL_HEADER), 1, fp); } 在我进行实验时, node_size目前为 4。