Code:
#define maxWords 200
//finput is the file
char tempWord[maxWords];
(for i = 0; i < lineCounter(f); i++)
{
fgets(tempWord, maxWords, finput);
printf("%s", tempWord);
}
The lineCounter function works fine and outputs the right amount of lines in the text file. But for some reason it prints only 150 lines out of 1500 lines which I don't understand. I've been trying other functions such as fscanf and others and I still have the same issue. They all print out text but not the WHOLE text file.
Even if I put i < 1500 as the condition in the for-loop I still have this problem. Does anyone know why? Also I tried in while-loop form too but no luck.
Also I know there are many topics related to reading a text file, I have read them but I still have this problem..
This small program should print out the line number and the line itself of an entire text file.
#define INPUT_FILE 1
#define LINE_LEN 200
int main(int argc, char *argv[]) {
int line_num;
char string[LINE_LEN];
FILE *file;
if((file = fopen(argv[INPUT_FILE], "r")) == NULL) {
fprintf(stderr, "Could not open input file\n");
exit(1);
}
line_num = 1;
while( fgets(string, LINE_LEN, file) != NULL ) {
line_num++
printf( "Line %d: <%s>\n", line_num, string);
}
return 0;
}
EDIT:
Initialized line_num to 1 and added the tags as suggested by #chux
Related
I'm new to programming in C. And I'm trying to print the first 10 lines of a text file. When I run my program with a text file containing 11 lines of text, only the first line is displayed. I'm not sure why it does that, but I suspect there is something wrong in my while loop. Can someone please help me?
#include <stdio.h>
int main(int argc, char *argv[]){
FILE *myfile;
char content;
int max = 0;
// Open file
myfile = fopen(argv[1], "r");
if (myfile == NULL){
printf("Cannot open file \n");
exit(0);
}
// Read the first 10 lines from file
content = fgetc(myfile);
while (content != EOF){
max++;
if (max > 10)
break;
printf ("%c", content);
content = fgetc(myfile);
}
fclose(myfile);
return 0;
}
You have been already advised to use fgets. However, if your file has lines of unknown length, you may still want to use fgetc. Just make sure you count only newlines, not all characters:
int max = 0;
int content;
while ((content = fgetc(myfile)) != EOF && max < 10){
if (content == '\n') max++;
putchar(content);
}
fgetc() returns the next character in the file, not the next line. You probably want to use fgets() instead, which reads up to the next newline character into a buffer. Your code should probably end up with something like:
// allocate 1K for a buffer to read
char *buff = malloc(1024);
// iterate through file until we are out of data or we read 10 lines
while(fgets(buff, 1024, myfile) != NULL && max++ < 10) {
printf("%s\n", buff);
}
free(buff);
// close your file, finish up...
Read more about fgets() here: https://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm
fgetc function reads the next character not the next ine. for reading the number of lines you should use fgets function. this function reads the full string till the end of the one line and stores it in a string.
your code Shuld be as:-
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *myfile;
char content[200];
int max = 0;
// Open file
myfile = fopen(argv[1], "r");
if (myfile == NULL)
{
printf("Cannot open file \n");
exit(0);
}
// Read the first 10 lines from file
fgets(content, 200, myfile);
while (content != EOF)
{
max++;
if (max > 10)
break;
printf("%s", content);
fgets(content, 200, myfile);
}
fclose(myfile);
return 0;
}
So what I'm basically doing here is using a command line argument to open a file but only open it 4 lines at a time, then a prompt to print out add'l lines. I can get the file to print out but I cannot figure out how to get it to only print out a few lines at a time. This is where I'm at....thoughts?
#include <stdio.h>
int main(int argc, char *argv[])
{
char line[1000];
FILE *pt;
pt = fopen(argv[1], "r");
if(pt == NULL) return -1;
printf(argv[1], line);
while(fgets(line, 1000, pt) != NULL)
printf("%s", line);
fclose(pt);
return 0;
}
I start from strange line of your code, and then I will try to answer the question.
Statement
printf(argv[1], line);
make me curious - what you what to print, actually?
Here line is not initialized, and argv[1] can hardly be used as format line.
So I suppose it should be just
printf(argv[1]);
or
printf("Filename is %s\n", argv[1]);
As for reading from a file with name provided as argv[1] your code looks able to work, I mean your code read line by line till the end of file and prints these lines at the screen.
If you want to change this logic, e.g. read only 4 first line, add condition with counter, e.g.:
int cnt;
for (cnt = 0; cnt < 4; cnt++) // repeat reading 4 times
{
if (fgets(line, 1000, pt) != NULL)
printf("%s", line);
else
break; // stop when reading fails
}
or (I prefer this version)
int cnt = 0;
while (fgets(line, 1000, pt) != NULL && cnt < 4)
{
printf("%s", line);
cnt++;
}
Such changes allows to stop reading (as well as output), so only 4 or less lines will be shown at console screen.
Finally, for case when you want to show file by groups of 4 (or other constant value), consider the following snippet:
#include <stdio.h>
#define MAX_LINES_TO_PRINT 4
int main(int argc, char *argv[])
{
char line[1000];
FILE *pt;
pt = fopen(argv[1], "r");
if (pt == NULL) return -1;
printf("Filename is %s\n", argv[1]);
int cnt = 0;
while (fgets(line, 1000, pt) != NULL)
{
printf("%s", line);
cnt++;
if (cnt % MAX_LINES_TO_PRINT == 0)
{
int answer;
printf("[%d lines printed] Continue? (Y/N) : ", cnt);
answer = getchar(); // get user's response
while (getchar() != '\n'); // clean input buffer after getchar
if (toupper(answer) == 'N')
{
break; // stop reading the file
}
}
}
fclose(pt);
return 0;
}
Try this program with your file and ask question if something is unclear.
Changing the value in the line #define MAX_LINES_TO_PRINT 4 you can regulate maximum number of lines printed at once (before the next request to continue), e.g. #define MAX_LINES_TO_PRINT 15 make your program printing up to 15 lines.
My main objective here is to make use of fscanf() to take in each word from my file and store it into an array location. As it stands, I loop through the file setting each word to a location in wordList[]. I can print out the values as they are put into the array and each seems to be placed correctly. But after the loop, when I attempt to print only one of the values (simply checking that everything went as it should) I get a weird output. When printing the string contained in wordList[5], it prints the first character of every word after location [5], and prints the last word that was collected.
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void readFile (FILE *fPtr, char *fileName) {
FILE *newFilePtr;
char wordList[1000];
int i = 0;
newFilePtr = fopen(strcat(fileName, ".out"), "w"); // Blank document created under same file name, but with ".out"
while(fscanf(fPtr, "%s", &wordList[i]) == 1) { // Read in strings from main file into wordList
printf("%s\n", &wordList[i]);
++i;
if (i > 10) // KEEP OUTPUT SHORT FOR STACK OVERFLOW QUESTION
break;
}
printf("%s\n", &wordList[5]); // PRINTS WILD VALUE AT POSITION 5
fclose(newFilePtr);
}
int main (int argc, char *argv[]) {
int lineSize;
char *fileName = argv[2]; // Store name of file for future operations
FILE *fPtr;
if (argc != 3) {
fprintf(stderr, "%s", "ERROR: Incorrect arguments. Please input a line size and a file.\n");
return;
}
lineSize = atol(argv[1]); // Convert string to it's integer equivalent
if (lineSize < 25 || lineSize > 100) {
fprintf(stderr, "%s", "ERROR: Line size not within range.\n");
return;
}
if (fPtr = fopen(fileName, "r")) { // If the file exists, open it for reading
readFile(fPtr, fileName);
puts("FILE OPENED SUCCESS");
fclose(fPtr);
} else {
fprintf(stderr, "%s", "ERROR: File could not be opened.\n");
return;
}
return;
}
And my current output (constrained to just the first 10 values to keep it short):
Mason–Dixon
Line
(or
Mason
and
Dixon's
Line)
was
surveyed
between
1763
DLwsb1763 // Should print "Dixon's" (the string at location 5)
FILE OPENED SUCCESS
The creation of the new file at line 11 is for later use when the file is formatted. For now, i'm only concerned with properly scanning in the values from the original file.
I have created a function that takes as a parameter the name of a source file, the name of a destination file and the beginning and end lines of the source file lines that will be copied to the destination file, like the example below. All I want to do is to input the lines that I want to copy to the other text file like the example below:
The code I show you just "reads" the content of the one text file and "writes" another one. I want to "write" specific lines that the user gives, not the whole text file
Inputs by the user:
Source_file.txt //the file that the destination file will read from
destination_file.txt //the new file that the program has written
2 3 // the lines that it will print to the destination file: 2-3
Source_file.txt:
1
2
3
4
5
6
destination_file.txt
2
3
code:
#include <stdio.h>
#include <stdlib.h>
void cp(char source_file[], char destination_file[], int lines_copy) {
char ch;
FILE *source, *destination;
source = fopen(source_file, "r");
if (source == NULL) {
printf("File name not found, make sure the source file exists and is ending at .txt\n");
exit(EXIT_FAILURE);
}
destination = fopen(destination_file, "w");
if (destination == NULL) {
fclose(source);
printf("Press any key to exit...\n");
exit(EXIT_FAILURE);
}
while ((ch = fgetc(source)) != EOF)
fputc(ch, destination);
printf("Copied lines %d from %s to %s \n",
lines_copy, source_file, destination_file, ".txt");
fclose(source);
fclose(destination);
}
int main() {
char s[20];
char d[20];
int lines;
printf("-Enter the name of the source file ending in .txt\n"
"-Enter the name of the destination file ending in .txt\n"
"-Enter the number of lines you want to copy\n\n");
printf(">subcopy.o ");
gets(s);
printf("destination file-> ");
gets(d);
printf("Lines: ");
scanf("%d", &lines);
cp(s, d, lines);
return 0;
}
In cp(), in order to select the lines to keep, you have to know their position in the input-file. Thus, you need to count lines.
Using fgets instead of fgetc will allow you to count the lines.
On the other hand, if I wanted to select lines 3 and 7 to 12 in a file, I'd use:
sed -n -e "3p;7,12p" < input.txt > output.txt
this is a very simple solution, let's say you know that the maximun length of a line will be 100 characters for simplicity (if a line is longer than 100 characters only the first 100 will be taken)
at the top (outside main) you can write
#ifndef MAX_LINE_SIZE
#define MAX_LINE_SIZE 100
#endif
i know many people don't like this but i think in this case it makes the code more elegant and easier to change if you need to modify the maximum line size.
to print only the wanted lines you can do something like this
char line[MAX_LINE_SIZE];
int count = 0;
while (fgets(line, MAX_LINE_SIZE, source)){
count++;
if (3 <= count && count <= 5){
fputs(line, destination);
}
}
The while loop will end when EOF is reched because fgets returns NULL.
P.S. there could be some slight errors here and there since i wrote it pretty fast and going by memory but in general it should work.
There are some problems in your program:
Do not use gets(), it may cause buffer overflows.
Always use type int to store the return value of fgetc() in order to distinguish EOF from regular byte values.
You pass an extra argument ".txt" to printf(). It will be ignored but should be removed nonetheless.
To copy a range of lines from source to destination, you can just modify your function this way:
#include <stdio.h>
#include <string.h>
#include <errno.h>
void cp(char source_file[], char destination_file[], int start_line, int end_line) {
int ch;
int line = 1, lines_copied;
FILE *source, *destination;
source = fopen(source_file, "r");
if (source == NULL) {
printf("Cannot open input file %s: %s\n",
source_file, strerror(errno));
exit(EXIT_FAILURE);
}
destination = fopen(destination_file, "w");
if (destination == NULL) {
printf("Cannot open output file %s: %s\n",
destination_file, strerror(errno));
fclose(source);
exit(EXIT_FAILURE);
}
while ((ch = fgetc(source)) != EOF) {
if (line >= start_line && line <= end_line) {
fputc(ch, destination);
}
if (ch == '\n') {
line++;
}
}
lines_copied = 0;
if (line > start_line) {
if (line >= end_line) {
lines_copied = end_line - start_line + 1;
} else {
lines_copied = line - start_line + 1;
}
}
printf("Copied lines %d from %s to %s\n",
lines_copy, source_file, destination_file);
fclose(source);
fclose(destination);
}
int main() {
char source_file[80];
char destination_file[80];
int start_line, end_line;
printf("-Enter the name of the source file ending in .txt\n"
"-Enter the name of the destination file ending in .txt\n"
"-Enter the start and end line\n\n");
printf(">subcopy.o ");
if (scanf("%79s", source_file) != 1) {
return 1;
}
printf("destination file-> ");
if (scanf("%79s", destination_file) != 1) {
return 1;
}
printf("Start and end lines: ");
if (scanf("%d %d", &start_line, &end_line) != 2) {
return 1;
}
cp(source_file, destination_file, start_line, end_line);
return 0;
}
I currently have a shell script in C that takes a command of a file, two numbers, mth line and nth line, and supposedly should output whats in between those lines:
for example:
./output file1 2 6
would output file from line 2 to line 6
I have it implemented currently in a way of outputting the whole file, I have been trying to change it to output specifically between those lines
this is my code
#include <fcntl.h>
int main(int argc, char *argv[])
{
int file;
int size;
int l[1000];
int firstNum = atoi(argv[2]);
int secondNum = atoi(argv[3]);
file = open(argv[1], O_RDONLY);
if( file == -1)
{
printf("\n cannot open file \n");
}
while ((size=read(file,l,80)) > 0)
write(1,l,size);
}
I tried to change l and size to firstNum and secondNum, which are the numbers entered from the command line, but still did not work and outputted one single line.
What is a better way of doing so ?
There are several issues with your code, so just go through them sequentially:
It's better to use high level fopen rather than low level open to open a file. So it's better to write this way:
FILE *file = fopen(argv[1], "r");
if (file == NULL)
exit(EXIT_FAILURE);
Your read is wrong as it reads exactly 80 characters instead of a line as you expect.
while ((size=read(file,l,80)) > 0) // <-- WRONG because this reads 80 chars instead of one line
For similar reason as with open, it's better to use alternative like printf instead of low level read and write.
To read line by line, you should use library function getline.
To control what line number to print, a simple way is to have a variable tracking what line number and compare with your command line arguments.
So put them together, you would need something like this:
FILE *file = fopen(argv[1], "r");
if (file == NULL)
exit(EXIT_FAILURE);
int line_num = 0;
char * line = NULL;
size_t len = 0;
ssize_t read = 0;
while ((read = getline(&line, &len, file)) != -1)
{
line_num++;
if( firstNum <= line_num && line_num <= secondNum )
{
printf( "line %d: %s", line_num, line );
if( line_num == secondNum )
break;
}
}
Try looking at this post: C read file line by line
From there it should be a simple matter of counting lines read and discarding them until you have read firstNum lines at which point print until you've reached secondNum.