Hi I have recently been given a task in C.
The aim of the task is to read from two text files and output each line of each file side by side with a separator string in the middle of said lines.
Example:
file 1 contains:
green
blue
red
file 2 contains:
rain
sun
separator string = xx
output =
greenxxrain
bluexxsun
redxx
I have managed to do this but was wondering if anyone else has any alternatives. Here is my code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int f1, f2;
FILE *file1, *file2;
file1 = fopen("textone", "r"); //open file1 for reading.
file2 = fopen("texttwo", "r"); //open file2 for reading.
//if there are two files ready, proceed.
if (file1 && file2){
do{
//read file1 until end of line or end of file is reached.
while ((f1 = getc(file1)) != '\n' && f1!= EOF ){
//write character.
putchar(f1);
}
//print separator string.
printf("xx");
//read file2 until end of line or end of file is reached.
while ((f2 = getc(file2)) != '\n' && f2!= EOF ){
//write character.
putchar(f2);
}
putchar('\n');
//do this until both files have reached their end.
}while(f1 != EOF || f2 != EOF);
}
}
You might find fgets(3) useful. It can be used to read a whole line at once. That said, it has downsides, too - you need to know how long the line is going to be, for example, or at least handle the case where the line is longer than your buffer. Your implementation seems fine to me (except that you should call fclose(3)).
You could write a simple function to avoid the 'big' repetition in the do { ... } while loop:
static void read_and_echo_line(FILE *fp)
{
int c;
while ((c = getc(fp)) != EOF && c != '\n')
putchar(c);
}
...
do
{
read_and_echo_line(file1);
printf("xx");
read_and_echo_line(file2);
putchar('\n');
} while (!feof(file1) || !feof(file2));
In this context, it is fairly reasonable to use feof() as shown (though it is not a function to use most of the time). Alternatively:
static int read_and_echo_line(FILE *fp)
{
int c;
while ((c = getc(fp)) != EOF && c != '\n')
putchar(c);
return(c);
}
...
do
{
f1 = read_and_echo_line(file1);
printf("xx");
f2 = read_and_echo_line(file2);
putchar('\n');
} while (f1 != EOF || f2 != EOF);
Related
My Code is HERE
int main(){
FILE *fp;
fp = fopen("dic.txt", "r");
while(getc(fp) != EOF){
if(getc(fp) == ' '){
printf("up ");
}
}
}
My dic.txt is HERE
dic.txt
my predict is that "up up up up "
because, there are four space " "
but it printed "up " only one
what is problem?
You are calling getc twice per iteration of the loop; one of these two calls compares the character to EOF, while the other call compares the character to ' '.
This has two consequences:
Your program will only print "up" for the spaces which are on even position, and will miss all spaces which are on odd position;
Your program might make one extra call to getc after reaching EOF the first time.
How to fix
You need to make a single call to getc per iteration of the loop. Save the character returned by getc to a local variable; then use this variable to check for spaces in the body of the loop, and to check for EOF in the condition of the loop.
You want this:
#include <stdio.h>
int main() {
FILE* fp;
fp = fopen("dic.txt", "r");
if (fp == NULL)
{
printf("Can't open file\n");
return 1;
}
int ch; // int is needed her, not char !!
while ((ch = getc(fp)) != EOF) { // read one char and check if it's EOF in one go
if (ch == ' ') {
printf("up ");
}
}
}
You need to call getc once only in the loop, otherwise you skip one out of two characters.
Bonus: you need to check if fopen fails.
Try Out This Code:
FILE *fp;
fp = fopen("dic.txt", "r");
int ch = getc(fp);
while(ch != EOF){
if(getc(fp) == ' '){
printf("up ");
}
}
return 0;
I have a list of columns containing text but I just to fetch first upper row from this list. How to do that?
#include <stdio.h>
int main()
{
FILE *fr;
char c;
fr = fopen("prog.txt", "r");
while( c != EOF)
{
c = fgetc(fr); /* read from file*/
printf("%c",c); /* display on screen*/
}
fclose(fr);
return 0;
}
Your stop condition is EOF, everything will be read to the end of the file, what you need is to read till newline character is found, furthermore EOF (-1) should be compared with int type.
You'll need something like:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fr;
int c;
if(!(fr = fopen("prog.txt", "r"))){ //check file opening
perror("File error");
return EXIT_FAILURE;
}
while ((c = fgetc(fr)) != EOF && c != '\n')
{
printf("%c",c); /* display on screen*/
}
fclose(fr);
return EXIT_SUCCESS;
}
This is respecting your code reading the line char by char, you also have the library functions that allow you to read whole line, like fgets() for a portable piece of code, or getline() if you are not on Windows, alternatively download a portable version, and, of course you can make your own like this one or this one.
For whatever it's worth, here's an example that uses getline
#include <stdio.h>
int main()
{
FILE *fr;
char *line = NULL;
size_t len = 0;
ssize_t nread;
if (!(fr = fopen("prog.txt", "r"))) {
perror("Unable to open file");
return 1;
}
nread = getline(&line, &len, fr);
printf("line: %s, nread: %ld\n", line, nread);
fclose(fr);
return 0;
}
Some notes:
getline() can automatically allocate your read buffer, if you wish.
getline() returns the end of line delimiter. You can always strip it off, if you don't want it.
It's ALWAYS a good idea to check the status of I/O calls like "fopen()".
just replace EOF as '\n'(new line char). Than your code will read until reaching the new line. Here is what it looks like:
#include <stdio.h>
int main()
{
FILE *fr;
char c = ' ';
fr = fopen("prog.txt", "r");
while(c != EOF && c != '\n')
{
c = fgetc(fr); /* read from file*/
if(c != EOF){
printf("%c",c); /* display on screen*/
}
}
fclose(fr);
return 0;
}
I have not tested it yet but probably work. Please let me know if there is some problem with the code i will edit it.
Edit1:char c; in line 5 is initialized as ' ' for dealing with UB.
Edit2:adding condition (c != EOF) to while loop in line 7, for not giving reason to infinite loop.
Edit3:adding if statement to line 10 for not printing EOF which can be reason for odd results.
I need to write some code to read an equation from a text file and write the answer to a new one, and I'm completely stuck
I've managed to read the question and print it in terminal as characters, but that's it.
this new code can't even do that.
for those asking, the exact wording of the question is this:
"Read an input file: questions.txt; and produce a program that creates an output file answers.txt that includes
the question and the answer for each line in the questions file.
For example, if the line in questions is:
5*5
the answer file should read:
5*5 = 25
Allow for the following operations: +, -, *, /, % and for the correct order of operations. Also allow for at least 2
operators (3 operands), for example:
3+5*5 = 28"
My main problem is reading the equation from the text file and separating it into numbers and the operator symbol
FILE *fp;
int a, b, c, ch, i, number[100];
char input[5];
fp = fopen ("questions.txt", "r");
while(1)
{
ch = fgetc(fp);
if (ch == EOF)
{
break;
}
else
{
input[i] = ch;
}
}
fclose(fp);
printf("%s", input);
}
There are errors:
check file has been open correcly: if (fp != NULL)
i = 0; on begin, now we dont know value
input[i] = ch; => input[i++] = (char)ch;
if (ch == EOF) => if (ch == EOF && i < 4) 4 because 5 - 1 and move this to const or macro
After break of while input[i] = '\0';
You need to open the file you want to read from in read mode with the normal fopen('questions.txt', 'r') like you did. Next, you need to fopen('newFile.txt', 'w') you want to write to in w write mode. Use a while loop to get each character of the questions.txt file with getc(fileToRead) while you haven''t hit the end of the questions.txt file, hence ... != EOF, and write to the newFile.txt. The printf("%c", c) is to print each character as you read it from questions.txt.
FILE *fileToRead, *fileToWrite;
int c;
//open the questions.txt file in read mode
*fileToRead = fopen ("questions.txt", "r");
//create newFile.txt and open it in write mode
*fileToWrite = fopen ("newFile.txt", "w");
while ((c = getc(fileToRead)) != EOF) {
putc((char)c, fileToWrite );
printf("%c", (char)c);
}
fclose(fileToRead);
fclose(fileToWrite);
I want to write a text and save it in .txt using <stdio.h> and <stdlib.h>. But with this way, I only could save one line, no more.
int main()
{
file*pf;
char kar;
if ((pf = fopen("try.txt","w")) == NULL)
{
printf("File couldn't created!\r\n");
exit(1);
}
while((kar=getchar()) != '\n')
fputc(kar, pf);
fclose(pf);
}
Instead of
char kar;
...
while((kar=getchar()) != '\n')
fputc(kar, pf);
use
int kar;
// Use int for type of kar
...
while((kar=getchar()) != EOF )
// ^^^
fputc(kar, pf);
'\n' means end of line. Here, you are looking for end of file. So, use macro EOF instead of '\n' in your code.
Full Working Code which puts multiple line into your text file. To end the input from terminal just press Ctrl + Z
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *pf;
char kar;
if ((pf = fopen("try.txt","w")) == NULL)
{
printf("File couldn't created!\r\n");
exit(1);
}
while((kar=getchar()) != EOF)
fputc(kar, pf);
fclose(pf);
return 0;
}
[Solved] Writing parsing code is a trap. A line with 15 spaces will have 15 words. Blank lines will also count as a word. Back to flex and bison for me.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
FILE *fp = NULL;
int iChars =0, iWords =0, iLines =0;
int ch;
/* if there is a command line arg, then try to open it as the file
otherwise, use stdin */
fp = stdin;
if (argc == 2) {
fp = fopen(argv[1],"r");
if (fp == NULL) {
fprintf(stderr,"Unable to open file %s. Exiting.\n",argv[1]);
exit(1);
}
}
/* read until the end of file, counting chars, words, lines */
while ((ch = fgetc(fp)) != EOF) {
if (ch == '\n') {
iWords++;
iLines++;
}
if (ch == '\t' || ch == ' ') {
iWords++;
}
iChars++;
}
/* all done. If the input file was not stdin, close it*/
if (fp != stdin) {
fclose(fp);
}
printf("chars: %d,\twords: %d,\tlines: %d.\n",iChars,iWords,iLines);
}
TEST DATA foo.sh
#!/home/ojblass/source/bashcrypt/a.out
This is line 1
This is line 2
This is line 3
ojblass#linux-rjxl:~/source/bashcrypt>
wc foo.sh
5 13 85 foo.sh
ojblass#linux-rjxl:~/source/bashcrypt>
a.out foo.sh
chars: 85, words: 14, lines: 5.
Your algorithm is wrong. If you have in the test file 2 blank characters in succession the counter for words will be incremented twice, but it should be incremented only once.
A solution will be to remember last character read. If the character read is a special character (blank, new line, ...) and the previous character is an alphanumeric then you increment the counter for words.
You are counting \n as a word even for a blank line.