program that writes the even and odd numbers - c

I was writting a program that can read a set of numbers file called dog.txt;
and also writes to two file separating odd and even. i was able to compile my program however, the output expected is not the same which was supposed to be even numbers in one file called EVEN, odd numbers in file odd.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int i;
int even,odd;
int num;
if (argc != 4) {
printf("Usage: executable in_file output_file\n");
exit(0);
}
FILE *dog = fopen(argv[1], "r");
FILE *feven= fopen(argv[2], "w");
FILE *fodd= fopen (argv[3], "w");
while (fscanf(dog, "%d", &num) != EOF)
{
if (0==i%2){
i++;
printf("even= %d\n", num);
}
else if(i!=0){
i++;
printf("odd= %d\n", num);
}
}
fclose(feven);
fclose(fodd);
fclose(dog);
return 0;
}
output:
even= 1
odd= 2
even= 34
odd= 44
even= 66
odd= 78
even= 94
odd= 21
even= 23
odd= 54
even= 44
odd= 65
even= 78
odd= 68
even= 92

You're checking i % 2, not num % 2. I'm not even sure what i does in this example—perhaps you're planning on using it later.
while (fscanf(dog, "%d", &num) != EOF) {
if (num % 2 == 0) {
printf("even = %d\n", num);
}
else if(num != 0) {
printf("odd = %d\n", num);
}
}
I imagine the code to write these numbers to the files will come later, once you've fixed this bug.

The code contains no instructions to write into the output files. It only writes to stdout.

In addition to the printf/fprintf problem, in any decent modern compiler, that code should be generating a warning that you're not assigning any initial value to i.

The printf function writes to the screen (more correctly, it writes to "standard output", but that is usually the screen). You want to write to a file. You have opened files called feven and fodd. To write to them, you would use the fprintf call, which works like printf except it takes an extra (left-most) argument, which is the FILE* that you want to write to, e.g.
FILE *fmyfile = fopen("myfile.txt", "w");
fprintf(fmyfile, "The magic number is %d!", 3);
Also, your results are incorrect, but that's an unrelated problem.

Related

Read problems using getw()

so I'm working on this program that read from a text file which is filled with non prime and prime numbers, so it first reads all the numbers from one text file and then it outputs only the prime numbers to another text file.
Let say one text file has:
233
179
178
199
198
157
On the second it should print or copy:
233
179
199
157
So far I have worked on the following code:
#include <stdio.h>
int main()
{
FILE *in_file;
int numbers;
in_file = fopen("file1.txt", "r");
while ( fscanf(in_file, "%d", &numbers) == 1) {
printf("%d\n", numbers);
}
fclose(in_file);
}
return 0;
}
The problem with the above code is that the reads are wrong, the output to the screen is not the same as in file1, and I'm not sure whether is to do with the getw() function or somewhere else in the code?
The int getw(FILE *) function is for reading an integer directly from the bytes of a file, not for reading an integer from the textual contents of a file.
If you wish to read integers from a file, one by one, use fscanf instead:
FILE *in_file = fopen("file1.txt", "r");
FILE *out_file = fopen("file2.txt", "w");
int num;
while (fscanf(in_file, "%d", &num) == 1) {
if (is_prime(num)) {
fprintf(out_file, "%d\n", num);
}
}
fclose(in_file);
fclose(out_file);

How to read space-separated values in C?

I have a .txt file that I am using to learn some basic C.
Here is the txt file:
8
12 48 15 65 16 82 9 72
Here is my C program:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv){
char num = 0;
//int[] arr = 0;
if (argc != 2){
return 0;
}
FILE *inputFile = fopen(argv[1], "r");
if (inputFile == NULL){
printf("Error1\n");
return 0;
}
while(!feof(inputFile)){
num = fgetc(inputFile);
printf("%c\n",num);
}
if(!feof(inputFile)){
printf("error");
return 0;
}
}
My goal is the get an array of the second line, based on the amount of values in the first line.... essentially, we want an array with 8 values, that stores {12, 48, ....}
You are using a wrong function to read integers: in spite of returning an int, function fgetc is reading individual characters (why getchar returns an int?).
In order to read space-separated integers, use fscanf instead, and check the return value to decide that you have reached the end of file:
int n;
while (fscanf(inputFile, " %d", &n) == 1) {
printf("%d\n", n);
}
Note that the loop above avoids using feof to detect the end of file condition (why using feof is wrong?)
If you aim to read a series of numbers (and nothing else), regardless of the number of line breaks in between, you could simply use fscanf as follows:
int num;
while(fscanf(inputFile, "%d", &num) == 1) {
printf("%d\n",num);
}
Note that fscanf returns the number of values successfully read in according to the format specifier, i.e. it returns 1 as long as an integral value could have been read in (and 0 otherwise).

error: used struct type value where scalar is required

I am creating a program which takes an input and opens a text file and changes words to lower or upper case depending on what the user wants. When I compile the program I gets the following error:
22:11: error: used struct type value where scalar is required
30:11: error: used struct type value where scalar is required
1 #include <stdio.h>
2 int main(void) {
3
4 char choice;
5 char fileName;
6 char newFileName;
7 int i = 0;
8
9 printf("Change Case \n");
10 printf("============\n");
11 printf("Case (U for upper, L for lower) : ");
12 scanf(" %c", &choice);
13 printf("Name of the original file : oldFile.txt \n");
14 printf("Name of the updated file : newFile.txt \n");
15
16 FILE *fp = NULL;
17
18 fp = fopen("oldFile.txt", "a");
19
20 if (fp != NULL && choice == 'L') {
21
22 while ( fp[i] ) {
23
24 putchar(tolower(fp[i]));
25 i++;
26 }
27 }
28 else if (fp != NULL && choice == 'U') {
29
30 while ( fp[i] ) {
31
32 putchar(toupper(fp[i]));
33 i++;
34 }
35 }
36 else {
37
38 printf("ERROR: No proper choice was made \n");
39 }
40 }
fp is a file pointer, not an array of whats in your file. Have a look at use of fopen in a tutorial.
You will need to use something like fgets to read your file into a buffer. You can also use fgetc to read your file one character at a time.
wrong way accessing file pointer fp. It is an pointer to a file not a array character or string. Each time a file is opened, the system places the file pointer at the beginning of the file, which is offset zero.
Close the opened file every time after processing using fclose(fP);
sample example code snippet of using file pointer.
int c;
fp = fopen("file.txt","r");
while(1)
{
c = fgetc(fp);// or fgets as per the usage
if( c==EOF)
{
//Exit
}
// your code
}
fclose(fp);
The file pointer is not an array... consider using fgetc/fgets. fp[i] doesn't give you the i-th byte of the file. fgetc will let you iterate over the bytes of the file and return EOF when you're at the end.
See the documentation for fgetc here.
Here is an example on how to acquire strings from txt. There are many other ways
#include <stdio.h>
int main(void) {
FILE *fp;
fp = fopen("oldFile.txt", "r");
char str[1024];
while(fgets(str, 1024, fp)!=NULL) { //acquire strings from oldFile.txt through fgets() which returns a pointer. NULL is returned at the end of file
printf("%s", str); //just an example
}
}

Reading a file 16 bytes at a time in C

I am trying to read a file parsed from a command line argument 16 bytes at a time. I am storing the bytes in an unsigned char array. I am then trying to print the elements in their HEX format and then, if they are printable characters, I am printing them and if not I am printing a dot "." I also would like to print the offset of the byte from the beggining of the file on each new line but I want to get the rest working before I start working on that. The problem I am having is the file I am reading from is not printing so I don't think I am doing it right. I started out using fread() but I think I may be needing to use fseek() but I am unsure. If anyone could point me in the right direction or tell me if I'm doing anything wrong I'd appreciate it.
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
FILE *fp;
int i, j;
unsigned char buffer[17];
fp = fopen(argv[1], "r");
while(!feof(fp))
{
while(fread(buffer, 16, 1, fp) !=0)
{
for(i=0; i < 16; i++)
{
printf("%X ", buffer[i]);
}
for(j = 0; j < 16; j++)
{
if(isprint(buffer[j]))
printf("%s", buffer[j]);
else
printf("." );
}
printf("\n");
}
}
fclose(fp);
return 0;
}
Expected output:
0001: 40 4F 28 37 0B B8 FF 9D 81 5E 2E 73 B5 CC 6A 70 #O(7.....^.s..jp
0010: 0F 30 9C 6E 7E F7 53 E0 C1 5E 9A 38 C5 02 F2 33 .0.n .S..^.8...3
EDIT: Fixed problem with suggestions. Was opening file in text mode instead of binary. Changed read mode to "rb" and code is working correctly now.
You need to open the file in binary mode, using fseek/ftell on a file in text mode gives erratic values.
So open the file with
fp = fopen(argv[1], "rb");
also good practice is to always check if a function succeeded by checking the return value, in this case if (fp != NULL) ...
Instead of reading 16 byte chunks read 1 byte 16 times, otherwise if the file length is not evenly dividable by 16 you miss the last bytes
if ( fp != NULL )
{
int read = 0;
while((read = fread(buffer, 1, 16, fp)) > 0)
{
for(i=0; i < read; i++)
{
...
}
fclose(fp);
}
IOW no need to for the outer while (feof(fp)) ...
in
printf("%s", buffer[j]);
you are not using the correct format specifier, buffer[j] is a character, not a string so write
printf("%c", buffer[j]);
EDIT: if you are not in some embedded environment with minimal stack reading 16 bytes at a time is not so effective, you can just as might read 2k or some bigger size to read faster.

Why doesn't fgets read whole line in while loop but works in for loop?

If my fgets is in a while loop, it only returns half the string. If it's in a for loop, it returns the whole string.. Any idea why?
Code below:
FILE *fp; // File pointer
char filename[] = "results.tsv";
fp = fopen(filename, "r"); // Open file argv[1] for READ
char s[4096];
int num = atoi(fgets(s, sizeof(s), fp)); // Get first line (number of units in file)
int i;
for(i = 0; i < num; i++)
{
printf("%s", fgets(s, sizeof(s), fp)); // Prints everything
}
while (fgets(s, sizeof(s), fp) != NULL) // Loop until no more lines
{
printf("%s\n", s); // Only prints the x's
}
fclose(fp); // Close file
And the files contents:
1
xxxxxxxx yyyy eee
Where the big spaces are tabs (\t).
If I run it, I get:
For loop only:
xxxxxxxx yyyy eee
While loop only:
xxxxxxxx
Thanks.
As already diagnosed, your code 'works for me'. Here's the SSCCE I created for it. If invoked with no arguments, it uses the while loop. If invoked with any arguments, it uses the for loop. Either way, it works correctly for me. Note that the code doesn't use the return value from fgets() directly; it checks that the input operation succeeded before doing so. It also echos what it is doing and reading as it goes.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
FILE *fp;
char filename[] = "results.tsv";
if ((fp = fopen(filename, "r")) == 0)
{
fprintf(stderr, "%s: failed to open file %s\n", argv[0], filename);
exit(1);
}
char s[4096];
if (fgets(s, sizeof(s), fp) == 0)
{
fprintf(stderr, "Premature EOF\n");
exit(1);
}
int num = atoi(s);
printf("Num lines: %d\n", num);
if (argc > 1)
{
printf("For loop:\n");
for (int i = 0; i < num; i++)
{
if (fgets(s, sizeof(s), fp) == 0)
{
fprintf(stderr, "Premature EOF\n");
exit(1);
}
printf("%d: %s", i+1, s);
}
}
else
{
int i = 0;
while (fgets(s, sizeof(s), fp) != NULL)
{
printf("While loop:\n");
printf("%d: %s", ++i, s);
}
}
fclose(fp);
return 0;
}
If you use this code and it fails on your system, then you could submit your evidence. Amongst other things, you should identify the platform on which you're working, and you should give a hex dump (or equivalent) of the data in the file results.tsv. The data file I used, for example, contained the bytes:
0x0000: 31 0A 78 78 78 78 78 78 78 78 09 79 79 79 79 09 1.xxxxxxxx.yyyy.
0x0010: 65 65 65 65 0A eeee.
0x0015:
Before start reading with while loop, you have to make the position of reading from the stream(file) start at the same position where the for loop start reading
You can do it with one of the 2 ways:
1) close the file and reopen it and read the first line before starting the while loop
2) Use the fseek (as KiriliKirov said) to point at the same position where the for loop start reading. To do you have get the current position (position where the for loop start reading) with the ftell() function:
int num = atoi(fgets(s, sizeof(s), fp));
long int start_read = ftell (fp); // get the current postion //add this line in your code
.....
fseek ( fp , start_read , SEEK_SET ); // add this line in your code
while (fgets(s, sizeof(s), fp) != NULL)
The second solution will avoid the close and the reopen the file and the read of the first line.
ftell() returns the current value of the position indicator of the stream.
fseek() Sets the position indicator associated with the stream to a new position

Resources