How to save results of a function into text file in C - c

This function print the length of words with '*' called histogram.How can I save results into text file? I tried but the program does not save the results.(no errors)
void histogram(FILE *myinput)
{
FILE *ptr;
printf("\nsaving results...\n");
ptr=fopen("results1.txt","wt");
int j, n = 1, i = 0;
size_t ln;
char arr[100][10];
while(n > 0)
{
n = fscanf(myinput, "%s",arr[i]);
i++;
}
n = i;
for(i = 0; i < n - 1; i++)
{
ln=strlen(arr[i]);
fprintf(ptr,"%s \t",arr[i]);
for(j=0;j<ln;j++)
fprintf(ptr, "*");
fprintf(ptr, "\n");
}
fclose(myinput);
fclose(ptr);
}

I see two ways to take care of this issue:
Open a file in the program and write to it.
If running with command line, change the output location for standard out
$> ./histogram > outfile.txt
Using the '>' will change where standard out will write to. The issue with '>' is that it will truncate a file and then write to the file. This means that if there was any data in that file before, it is gone. Only the new data written by the program will be there.
If you need to keep the data in the file, you can change the standard out to append the file with '>>' as in the following example:
$> ./histogram >> outfile.txt
Also, there does not have to be a space between '>' and the file name. I just do that for preference. It could look like this:
$> ./histogram >outfile.txt
If your writing to a file will be a one time thing, changing standard out is probably be best way to go. If you are going to do it every time, then add it to the code.
You will need to open another FILE. You can do this in the function or pass it in like you did the file being read from.
Use 'fprintf' to write to the file:
int fprintf(FILE *restrict stream, const char *restrict format, ...);
Your program may have these lines added to write to a file:
FILE *myoutput = fopen("output.txt", "w"); // or "a" if you want to append
fprintf(myoutput, "%s \t",arr[i]);
Answer Complete
There may be some other issues as well that I will discuss now.
Your histogram function does not have a return identifier. C will set it to 'int' automatically and then say that you do not have a return value for the function. From what you have provided, I would add the 'void' before the function name.
void histogram {
The size of arr's second set of arrays may be to small. One can assume that the file you are reading from does not exceed 10 characters per token, to include the null terminator [\0] at the end of the string. This would mean that there could be at most 9 characters in a string. Else you are going to overflow the location and potentially mess your data up.
Edit
The above was written before a change to the provided code that now includes a second file and fprintf statements.
I will point to the line that opens the out file:
ptr=fopen("results1.txt","wt");
I am wondering if you mean to put "w+" where the second character is a plus symbol. According to the man page there are six possibilities:
The argument mode points to a string beginning with one of the
following sequences (possibly followed by additional characters, as
described below):
r Open text file for reading. The stream is positioned at the
beginning of the file.
r+ Open for reading and writing. The stream is positioned at the
beginning of the file.
w Truncate file to zero length or create text file for writing.
The stream is positioned at the beginning of the file.
w+ Open for reading and writing. The file is created if it does
not exist, otherwise it is truncated. The stream is
positioned at the beginning of the file.
a Open for appending (writing at end of file). The file is
created if it does not exist. The stream is positioned at the
end of the file.
a+ Open for reading and appending (writing at end of file). The
file is created if it does not exist. The initial file
position for reading is at the beginning of the file, but
output is always appended to the end of the file.
As such, it appears you are attempting to open the file for reading and writing.

Related

fread is not reading whole file [duplicate]

What translation occurs when writing to a file that was opened in text mode that does not occur in binary mode? Specifically in MS Visual C.
unsigned char buffer[256];
for (int i = 0; i < 256; i++) buffer[i]=i;
int size = 1;
int count = 256;
Binary mode:
FILE *fp_binary = fopen(filename, "wb");
fwrite(buffer, size, count, fp_binary);
Versus text mode:
FILE *fp_text = fopen(filename, "wt");
fwrite(buffer, size, count, fp_text);
I believe that most platforms will ignore the "t" option or the "text-mode" option when dealing with streams. On windows, however, this is not the case. If you take a look at the description of the fopen() function at: MSDN, you will see that specifying the "t" option will have the following effect:
line feeds ('\n') will be translated to '\r\n" sequences on output
carriage return/line feed sequences will be translated to line feeds on input.
If the file is opened in append mode, the end of the file will be examined for a ctrl-z character (character 26) and that character removed, if possible. It will also interpret the presence of that character as being the end of file. This is an unfortunate holdover from the days of CPM (something about the sins of the parents being visited upon their children up to the 3rd or 4th generation). Contrary to previously stated opinion, the ctrl-z character will not be appended.
In text mode, a newline "\n" may be converted to a carriage return + newline "\r\n"
Usually you'll want to open in binary mode. Trying to read any binary data in text mode won't work, it will be corrupted. You can read text ok in binary mode though - it just won't do automatic translations of "\n" to "\r\n".
See fopen
Additionally, when you fopen a file with "rt" the input is terminated on a Crtl-Z character.
Another difference is when using fseek
If the stream is open in binary mode, the new position is exactly offset bytes measured from the beginning of the file if origin is SEEK_SET, from the current file position if origin is SEEK_CUR, and from the end of the file if origin is SEEK_END. Some binary streams may not support the SEEK_END.
If the stream is open in text mode, the only supported values for offset are zero (which works with any origin) and a value returned by an earlier call to std::ftell on a stream associated with the same file (which only works with origin of SEEK_SET.
Even though this question was already answered and clearly explained, I think it would be interesting to show the main issue (translation between \n and \r\n) with a simple code example. Note that I'm not addressing the issue of the Crtl-Z character at the end of the file.
#include <stdio.h>
#include <string.h>
int main() {
FILE *f;
char string[] = "A\nB";
int len;
len = strlen(string);
printf("As you'd expect string has %d characters... ", len); /* prints 3*/
f = fopen("test.txt", "w"); /* Text mode */
fwrite(string, 1, len, f); /* On windows "A\r\nB" is writen */
printf ("but %ld bytes were writen to file", ftell(f)); /* prints 4 on Windows, 3 on Linux*/
fclose(f);
return 0;
}
If you execute the program on Windows, you will see the following message printed:
As you'd expect string has 3 characters... but 4 bytes were writen to file
Of course you can also open the file with a text editor like Notepad++ and see yourself the characters:
The inverse conversion is performed on Windows when reading the file in text mode.
We had an interesting problem with opening files in text mode where the files had a mixture of line ending characters:
1\n\r
2\n\r
3\n
4\n\r
5\n\r
Our requirement is that we can store our current position in the file (we used fgetpos), close the file and then later to reopen the file and seek to that position (we used fsetpos).
However, where a file has mixtures of line endings then this process failed to seek to the actual same position. In our case (our tool parses C++), we were re-reading parts of the file we'd already seen.
Go with binary - then you can control exactly what is read and written from the file.
In 'w' mode, the file is opened in write mode and the basic coding is 'utf-8'
in 'wb' mode, the file is opened in write -binary mode and it is resposible for writing other special characters and the encoding may be 'utf-16le' or others

How to use FILE in binary and text mode in C [duplicate]

What translation occurs when writing to a file that was opened in text mode that does not occur in binary mode? Specifically in MS Visual C.
unsigned char buffer[256];
for (int i = 0; i < 256; i++) buffer[i]=i;
int size = 1;
int count = 256;
Binary mode:
FILE *fp_binary = fopen(filename, "wb");
fwrite(buffer, size, count, fp_binary);
Versus text mode:
FILE *fp_text = fopen(filename, "wt");
fwrite(buffer, size, count, fp_text);
I believe that most platforms will ignore the "t" option or the "text-mode" option when dealing with streams. On windows, however, this is not the case. If you take a look at the description of the fopen() function at: MSDN, you will see that specifying the "t" option will have the following effect:
line feeds ('\n') will be translated to '\r\n" sequences on output
carriage return/line feed sequences will be translated to line feeds on input.
If the file is opened in append mode, the end of the file will be examined for a ctrl-z character (character 26) and that character removed, if possible. It will also interpret the presence of that character as being the end of file. This is an unfortunate holdover from the days of CPM (something about the sins of the parents being visited upon their children up to the 3rd or 4th generation). Contrary to previously stated opinion, the ctrl-z character will not be appended.
In text mode, a newline "\n" may be converted to a carriage return + newline "\r\n"
Usually you'll want to open in binary mode. Trying to read any binary data in text mode won't work, it will be corrupted. You can read text ok in binary mode though - it just won't do automatic translations of "\n" to "\r\n".
See fopen
Additionally, when you fopen a file with "rt" the input is terminated on a Crtl-Z character.
Another difference is when using fseek
If the stream is open in binary mode, the new position is exactly offset bytes measured from the beginning of the file if origin is SEEK_SET, from the current file position if origin is SEEK_CUR, and from the end of the file if origin is SEEK_END. Some binary streams may not support the SEEK_END.
If the stream is open in text mode, the only supported values for offset are zero (which works with any origin) and a value returned by an earlier call to std::ftell on a stream associated with the same file (which only works with origin of SEEK_SET.
Even though this question was already answered and clearly explained, I think it would be interesting to show the main issue (translation between \n and \r\n) with a simple code example. Note that I'm not addressing the issue of the Crtl-Z character at the end of the file.
#include <stdio.h>
#include <string.h>
int main() {
FILE *f;
char string[] = "A\nB";
int len;
len = strlen(string);
printf("As you'd expect string has %d characters... ", len); /* prints 3*/
f = fopen("test.txt", "w"); /* Text mode */
fwrite(string, 1, len, f); /* On windows "A\r\nB" is writen */
printf ("but %ld bytes were writen to file", ftell(f)); /* prints 4 on Windows, 3 on Linux*/
fclose(f);
return 0;
}
If you execute the program on Windows, you will see the following message printed:
As you'd expect string has 3 characters... but 4 bytes were writen to file
Of course you can also open the file with a text editor like Notepad++ and see yourself the characters:
The inverse conversion is performed on Windows when reading the file in text mode.
We had an interesting problem with opening files in text mode where the files had a mixture of line ending characters:
1\n\r
2\n\r
3\n
4\n\r
5\n\r
Our requirement is that we can store our current position in the file (we used fgetpos), close the file and then later to reopen the file and seek to that position (we used fsetpos).
However, where a file has mixtures of line endings then this process failed to seek to the actual same position. In our case (our tool parses C++), we were re-reading parts of the file we'd already seen.
Go with binary - then you can control exactly what is read and written from the file.
In 'w' mode, the file is opened in write mode and the basic coding is 'utf-8'
in 'wb' mode, the file is opened in write -binary mode and it is resposible for writing other special characters and the encoding may be 'utf-16le' or others

Random writing order to output file?

I've written a program that writes information to a file. The output to the file is not in the order that I am expecting. I have a header line and three additional lines with numerical information. The header comes first following by the third, first, and second lines.
Note that the file is open in a mode, not a+. According to various sources, re-positioning operators like fseek() are suppose to be ignored. For a while I was actually getting the third line before the first line after that line was written. If the fseek() line is omitted, the third line actually is written before the header ..
If the fseek() function is left commented (regardless of being in a or a+ mode) the output is as shown in the picture below.
I wrote in a bit of code to see how the output should be written. The text in the file is certainly not what it should be ..
I attempted to use the fseek() function to find the position just before the EOF before each write but to no avail.
I have also noticed that if I use fflush(writeP) then I get the same effect that including the fseek() function would. The file is still out of order as shown, but the third line is no longer before the header line.
What am I missing?
void quickSortHelper(int* num, long startTime, long endTime, int size){
FILE *writeP = fopen(QUICKSORT_FILE, "a");
if(writeP == NULL){
fputs("Error opening file\n", stderr);
exit(1);
}
static int times = 0;
long deltaT; //change in time
if(size < STEPSIZE){//first time, write header to file
printf("Writing header!\n");
fprintf(writeP, " --- QUICKSORT ---\nCOUNT\tTIME\tMEDIAN\n");
}
deltaT = (clock() - startTime)/(CLOCKS_PER_SEC/1000);
//fflush(writeP);
fseek(writeP, -1, SEEK_END);
printf("Writing: %d\t%ld\t%d\n", size, deltaT, findMedian(num, size));
fprintf(writeP, "%d\t%ld\t%d\n", size, deltaT, findMedian(num, size));
if(++times == 3)
fclose(writeP);
return;
}
With the fseek() line commented, the output is:
You do not close writeP the first 3 times when function is called. So, the file is opened by several FILE handles which get closed on exit. The "a" works only for the same FILE handle or when data have reached the disk.
The problem comes from the fact that you open the same file on every function call, but only close it on the third call. I would suggest moving the file opening and closing logic out of that function, and passing the FILE * handle as an argument to the function; this would also avoid having to hard code the call number on which to close into that function.
So the place where you call the function would look something like this:
FILE *writeP = fopen(QUICKSORT_FILE, "w"); // "a" changed to "w"
if (!writeP) {
perror(QUICKSORT_FILE);
exit(1);
}
// perhaps write the header into the file here
for (int i = 0; i < 3; ++i) {
// do the quicksort
write_quicksort_results(writeP, …);
}
(void) fclose(writeP);

C programming; adding strings to beginning of line in file

I'm trying to add numbering to several lines of text in an existing .txt file using fopen's "r+" mode. This doesnt' seem to work and it ends up writing the first iteration of the string "line" followed by a large amount of junk value. Is there any way to add text at the beginning of a line? If so, am i coming at this the wrong way?
Also im trying to do this without having to write up a whole new file.
void main()
{
char read = ' ';
char buffer[25];
char line[4] = "01."; //lines from 01 to 99
FILE *file;
file = fopen("readme.txt","r+");
if (file == NULL)
{
printf("ERROR: Cannot open input file.\n");
exit();
}
do
{
fwrite(line,strlen(line),1,file);
read=gets(buffer);
if(!feof(file)) // updating line numbers
{
if(line[1]<'9')
{
(line[1])++;
}
else
{
if(line[0]<'9')
{
(line[0])++;
}
else
{
exit();
}
}
}
else
{
exit();
}
}while(!(feof(file)));
fclose(file);
exit();
}
Files in C let you overwrite and append, but not "prepend" data. To insert at the beginning or in the middle, you must copy the "tail" manually.
If you are writing a line-numbering program, it would be much simpler (and faster) to write the result into a separate temporary file, and then copy it in place of the original once the operation is complete.
You can use a simple loop that reads the original file line-by-line, and writes the output file, for example, with fprintf:
fprintf(outFile, "%02d.%s", lineNumber++, lineFromOrigFile);
No, there is no portable/standard way of doing what you want.
Files are random access, but you can't insert data into a file since that would force all the other data to move, which is not an operation supported by typical file systems.
The best solution is to do it in two steps:
Read through the input, while writing output to a new file
Rename the new file to replace the original input
While the answers are correct and you can't add a string in the beginning of a file in C (using only FILE commands), you can interact with the operating system and use bash command 'sed' (in Linux) that solve the problem pretty easily without creating a new file and copy the content of the older file.
void AddTextToFirstLine(const char* file_name, const char* text)
{
char command_string[100]; //Preferably some constant but can be done with malloc of size strlen(text) + strlen(file_name) + 16 (chars in the command + nullbyte)
sprintf(command_string, "sed -i '1 i\\%s' %s", text, file_name);
system(command_string); //executing the sed command
}
You can also look for the equivalent of 'sed' in Unix system for Windows: Is there any sed like utility for cmd.exe?
Although calling the operating system is not recommended usually (because every operating system action stops the program flow and therefore damage time efficiency) This is one of the rare cases in which its ok since we're calling the operating system anyway when we're creating a file (or a copy file in that case). Therefore using this method will also decrease the running time compare to the solution of creating a copy file and copy the content of the old file to it.
Adding string in the beginning of file is just like inserting.
And you can't really directly insert string using C, instead you will overwrite old content.
So you can only do an overhaul to the text file:
record old file content somewhere(temp file or memory...etc), write your string, then paste old content back.

Trying not to overwrite a file in C?

Hi I'm trying not to overwrite a file in C using fopen(file, "w");
My question is the file already exists as a 10 MB file but when I used the fopen the file ends up becoming 1KB. I want to write something to the file but I want it to stay the same size as well. How would I accomplish this? I saw that the "a+" appends things to the end of the file but what if I want to write something to the beginning of the file without expanding the size? It's just an empty file
Alternatively, is there a way to create a file in C with a certain size (such as 10MB)?
Yes, it is possible. By opening it with r+ you open it for 'reading and writing' (while w opens it for writing freshly).
Regarding your other question: Open a file with w and write 1000 1024 byte blocks to the file like this:
FILE *fp = fopen("file", "wb");
if(fp) {
int i = 0;
char Buf[1024];
for(; i < 1000; ++i)
fwrite(Buf, 1, 1024, fp);
fclose(fp);
}
Just once more the fopen flags for you:
r -> Opens file for reading. (File remains unchanged)
w -> Opens file for writing. (File gets erased)
a -> Opens file for appending. (File remains unchanged, file pointer gets moved to end)
Aside from these three main types, you can add a few more additional options:
b -> Opens the file as binary, ignoring formatting characters like \n
t -> Opens the file as text, specifically parsing \n as \r\n under Windows.
Open the file, then use fseek to set your position to the beginning of your file.
Edit: use r+ mode when opening. From man fopen:
r+ Open for reading and writing. The stream is positioned at
the beginning of the file.
*a way to create a file in C with a certain size (such as 10MB)?
like this:
#include <stdio.h>
int main(void){
const char *TenMBfile = "TenMB";
FILE *fp;
fp=fopen(TenMBfile, "w");
fseek(fp, 10*1024*1024-1,SEEK_SET);
fputc(0, fp);
fclose(fp);
return 0;
}
Hye! I worked on a project for adding text or 'blog' post on my web page and I found a pretty cool way to do it.
For this, I'll use a HTML file and my program.
HTML FILE:
<html>
<body>
<p> Hey this is the asssdsadasdsadas paragraph</p><br>
<p> Hey this is the asssdsadasdsadas paragraph</p><br>
</body>
</html>
C FILE:
printf("Please enter the number of bytes to write from in %s .\n", argv[0]);
int offset;
scanf("%d", &offset);
fseek(fp, -offset, SEEK_END);
strcat(argv[1], "<br>\n\n");
fprintf(fp, "%s", argv[1]);
fprintf(fp, "</body>\n</html>\n");
HTML explanation:
I start with one line defined
I put a blank line which I am going to write there.
Then I got all my ending tags.
C explanation:
I ask how many bytes I want to seek from the ending of the file wich is 17 in this case(to write to the blank line).
I get the number with scanf()
Then I seek in the file at minus x bytes because normally it's going to add bytes and we specify the whence.
Then for the purpose, here I add a break tag and also 2 newline to continue the cycle.
Then I write my wanted text.
Last, I add my 2 last tags, because when I write my text, it overwrites all after it. So after, the cursor is positioned after the last newline and I can write the ending tags.
So... This is how you can do it.

Resources