I'm having trouble transferring data from a file to another file using C, and I would like some help from the community to help me troubleshoot some of the output problems. I'm doing this because I want to convert the txt data into binary data next. Totally testing purpose.
Here is the code I have so far:
int txt2txt()
{
FILE *pTextFile, *pBinaryFile;
char buffer[1000];
pTextFile = fopen ("AS001.txt","r");
pBinaryFile = fopen("BS001.txt","w");
while(fgets(buffer,1000,pTextFile)!=NULL){
fwrite(buffer,sizeof(int),sizeof(buffer),pBinaryFile);
}
fclose(pTextFile);
fclose(pBinaryFile);
return 0;
}
Sample input/output:
AS001.txt:
91829812
1231231
1231232
123231123
1232312
123123123
12312312
and output BS001.txt:
91829812
„w O]€©O] * + O] ¤O]H¨O] ¬O]( O] #¨O]Lü( ¾8„w8O]š8„w¥ex O]ˆ©O] O]8¤O] ¤O] ¤O]H¨O]`žO]H O] 8¤O]œü( ¾8„w8O]š8„wuex O]#¤O] ЪO]Q ø H¨O]PO] ¬O] O]PO]™Qº€O]PO] D Q Q ¬O] Q ˆ p¨O] ¬O]Õqˆw¹Qºþÿÿÿ|O]
This code:
while(fgets(buffer,1000,pTextFile)!=NULL){
fwrite(buffer,sizeof(int),sizeof(buffer),pBinaryFile);
}
Tries to read 1000 bytes and then writes 1000 * sizeof(int) bytes per iteration. Unless your system has 1-byte integers (unlikely), that's probably not what you wanted.
Besides that, fgets might not have filled up your entire buffer - it stops at a newline.
Use:
while (fgets(buffer, 1000, pTextFile) != NULL)
{
fwrite(buffer, 1, strlen(buffer), pBinaryFile);
}
Edit: Since you're having problems, here's a complete example. First, source code:
#include <stdio.h>
#include <string.h>
int main(void)
{
char buffer[1000];
FILE *pTextFile = fopen("AS001.txt","r");
FILE *pBinaryFile = fopen("BS001.txt","w");
while (fgets(buffer, 1000, pTextFile) != NULL)
{
fwrite(buffer, 1, strlen(buffer), pBinaryFile);
}
fclose(pTextFile);
fclose(pBinaryFile);
return 0;
}
Second, build & run:
$ make example
cc example.c -o example
$ cat AS001.txt
91829812
1231231
1231232
123231123
1232312
123123123
12312312
$ ./example
$ diff AS001.txt BS001.txt
$
Include the string.h from the standard library and change your write command to this:
fwrite(buffer, sizeof(char), strlen(buffer), pBinaryFile);
This will stop it from trying to write the junk data in the rest of the buffer, which is undefined.
Related
I am trying to using libzip to create a zip file directly in memory, not to a file on disk. My code is quite basic at the moment as I am getting stuck on creating the necessary zip_t struct from a zip_source_buffer:
#include <stdio.h>
#include <string.h>
#include <zip.h>
int main(int argc, char *arrv[])
{
char buffer[65536] = {};
zip_error_t error;
zip_source_t *zs = zip_source_buffer_create(buffer, sizeof(buffer), 0, &error);
int err = zip_source_begin_write(zs);
printf("%p %d '%s'\n", zs, err, zip_error_strerror(&error));
zip_error_fini(&error);
zip_t * zip = zip_open_from_source(zs, ZIP_CREATE, &error);
printf("%p '%s'\n", zip, zip_error_strerror(&error));
zip_error_fini(&error);
}
the code compiles and runs, but thows an error:
$ ./ztest
0xdd50a0 0 'No error'
(nil) 'Not a zip archive'
It's not clear if the begin_write() is needed, but it doesn't generate an error and I get the same result without it.
What am I missing? Thanks
My 2 cent if anybody yet has interest in question.
Do not forget to zip_source_keep before zip_open_from_source, as zip_close will free source, but we want to use its content.
int flags = 0;
zip_error_t error;
zip_source_t *zsmem = zip_source_buffer_create(0, 0, 0, &error);
//we can fill up new zip with an old one (some template, for example)
if (exdata){
zip_source_begin_write(zsmem);
zip_source_write(zsmem, exdata, exdata_sz);
zip_source_commit_write(zsmem);
}else
flags |= ZIP_TRUNCATE;
zip_source_keep(zsmem); //!!
struct zip* arc = zip_open_from_source(zsmem, flags, &error);
//do more stuff adding, removing files , comments, etc
zip_close(arc);
zip_source_open(zsmem);
zip_source_seek(zsmem, 0, SEEK_END);
zip_int64_t sz = zip_source_tell(zsmem);
zip_source_seek(zsmem, 0, SEEK_SET);
zip_source_read(zsmem, outbuffer, sz);
zip_source_close(zsmem);
zip_source_free(zsmem);
send_over_network(outbuffer);
Use ZIP_TRUNCATE instead of ZIP_CREATE. The archive always exists in the case of a buffer source, so ZIP_CREATE has no effect, but a stream of '0's is not a valid zip file. ZIP_TRUNCATE tells libzip to ignore the buffer's current contents (i.e. override all the '0's with the new archive).
zip_source_begin_write() is called internally by libzip. It's not necessary for it to be called in this kind of situation.
I'm trying to use plotutils to generate a plot from binary data. First, I wrote a C program to export some sample binary data. Then, when I execute the following command in terminal, the plot gets generated as expected.
graph -T png -I d <'/Users/username/Documents/Restofpath/PlotutilsDataGen/testData'> '/Users/username/Documents/Restofpath/PlotutilsDataGen/testPlot.png'
But I want to combine this command with the C code that generates the binary data file so that once the code is executed, the plot is automatically exported. I tried two approaches: (i) using popen() which I suspect I'm doing incorrectly, and (ii) using system() which I thought should work, but doesn't. My entire code is as follows (I've listed both approaches together in the code by I naturally tried them individually):
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int numSamples = 1024;
double outputVec[2*numSamples];
char outputPath[200] = "/Users/username/Documents/Restofpath/PlotutilsDataGen/testData";
char plotcommand[400] = "graph -T png -I d <'/Users/username/Documents/Restofpath/PlotutilsDataGen/testData'> '/Users/username/Documents/Restofpath/PlotutilsDataGen/testPlot.png'";
FILE *fp, *p;
// Compute sample functions to export
for(int ii = 0; ii < (2*numSamples); ii = ii + 2)
{
outputVec[ii] = (double)ii/2;
outputVec[ii+1] = (double)(ii*2);
}
// Export as binary data file for plotutils to use for plotting
fp = fopen(outputPath, "wb");
fwrite(outputVec, sizeof(double), 2*numSamples, fp);
fclose(fp);
// Option 1
p = popen(plotcommand, "w");
pclose(p);
// Option 2
system(plotcommand);
return 0;
}
Any ideas as to what I'm doing wrong or how I might get this to work? Thanks.
I'm working with some code written by someone else to scan key value string pairs from a config file. The code is:
void readProfile(char * profileName) {
FILE *f;
int i=0;
f = fopen(profileName, "r");
if (NULL != f) {
while (fscanf(f, "%s%s", &pvtProperties[i].key[0],
&pvtProperties[i].value[0]) == 2) {
i++;
}
fclose(f);
}
numberOfProperties = i;
setCurrentProfileName(profileName);
}
However when reading this plaintext config file below, it has a problem with the 4th line:, the value is truncated to "https://dev.xxxx.com:58443/services/PvtTransferSer". Each line of the config file is separated by \r\n. From that point on the reading of the rest of the file is messed up, values becoming keys etc. Why is this happening? The keys and values are char arrays of 80 chars each.
Config file:
PASSWORD xxxx
REMOTE_UPDATES_ENABLE 1
REMOTE_DIAGNOSTICS_ENABLE 1
PVT_TRANSFER_WS_ADDRESS https://www.xxxx.com:58443/services/PvtTransferService
PVT_DIAGNOSTIC_WS_ADDRESS https://www.xxxx.com:58443/services/PvtDiagnosticService
PVT_UPDATE_WS_ADDRESS https://www.xxxx.com:58443/services/PvtUpdateService
PVT_ADJUSTMENT_WS_ADDRESS https://www.xxxx.com:58443/services/PvtAdjustmentService
DAILY_RESTART_ENABLE 1
HOUR_PAST_MIDNIGHT_FOR_RESTART 7
MAX_RESTART_RANDOMIZATION_SECONDS 30
MINIMUM_UPTIME_SECONDS_BETWEEN_RESTARTS 7200
CLEAR_CACHE_ON_RESTART_ENABLE 0
MINIMUM_SECONDS_BETWEEN_REMOTE_UPDATE_CHECKS 3600
SECONDS_BETWEEN_CONTROLLER_CONFIGURATION_CHECKS 300
CONNECTIVITY_LOSS_DETECTION_ENABLE 1
SMART_COMM_ENABLE 1
TIME_SYNC_ENABLE 1
FACTORY_RESET_ENABLE 1
CM_POLL_PROTOCOL http
You can solve your phase issue by using fgets to pull a line in at a time from the file; then sscanf to parse that line buffer for each record.
The part of my code that I'm asking about looks like this.
My TXT is containing number from 1-20 divided by . I want to make a BINARY file
from this txt, that's what the program supposed to do, but it is only feeling it up with memory dirt. Can you tell me if my code has mistakes.
void txt_to_bin (void)
{
FILE *ft,*fb;
int a;
ft = fopen("binadatok.txt","rt");
fb = fopen("versenyazonosito.dat","wb");
while (fscanf(ft,"%d\n",&a) != EOF)
{
fprintf(fb,"%d\n");
}
}
You need to use fwrite when writing to a binary file, not fprintf:
fwrite(&a, sizeof(a), 1, fb);
you are not providing any value in fprintf(fb,"%d\n") you should provide input of a in this statement .
void txt_to_bin (void)
{
FILE *ft,*fb;
int a;
ft = fopen("binadatok.txt","rt");
fb = fopen("versenyazonosito.dat","wb");
while (fscanf(ft,"%d\n",&a) != EOF)
{
fprintf(fb,"%d\n",a);
}
}
now it will work.
I've defined a binary file like this in C
FILE *gfp;
gfp = fopen(gridfiles, "wb");
The variable gridfiles stores the name of the file, and has been defined earlier. Now I write out two variables into the file.
for(yy = 0; yy < nfiley; yy++) {
for(xx = 0; xx < nfilex; xx++) {
filebx = beguv + xx*1E3;
fileby = enduv - yy*1E3;
fwrite(&filebx, sizeof(filebx), 1, gfp);
fwrite(&fileby, sizeof(fileby), 1, gfp);
}
}
If right after this code I
fseek(gfp, 0, SEEK_SET);
fread(&filebx, sizeof(filebx), 1, gfp);
fread(&fileby, sizeof(fileby), 1, gfp);
fprintf(stderr, "%f %f", filebx, fileby);
my output is
1000 15000
for the first two, which is as expected.
But if after some assorted other code (that doesn't involve these files at all) I repeat the fseek() etc., my output is
14000 14000
regardless of what I do.
I've been trying to figure this out for a while now... anyone know what I'm doing wrong?
It's Undefined Behaviour to read from a stream which has been opened in write mode. You should make it:
gfp = fopen(gridfiles, "wb+");
if you plan to both read and write.
Also, as pointed out by #Kyle Jones in the comments above, you should get into the habit of checking the return status of fread/fwrite when doing file I/O - this would have caught your problem a lot earlier.