So i've been given an exercise to work on: Have the user input a number and the program will display the line of text associated with that line for example
Password
abcdefg
Star_wars
jedi
Weapon
Planet
long
nail
car
fast
cover
machine
My_little
Alone
Love
Ghast
Input 3: Output: Star_wars
Now i have been given a program to solve this, however it uses the function getline() , which doesn't complie on DEV C++.
#include <stdio.h>
int main(void)
{
int end = 1, bytes = 512, loop = 0, line = 0;
char *str = NULL;
FILE *fd = fopen("Student passwords.txt", "r");
if (fd == NULL) {
printf("Failed to open file\n");
return -1;
}
printf("Enter the line number to read : ");
scanf("%d", &line);
do {
getline(&str, &bytes, fd);
loop++;
if (loop == line)
end = 0;
}while(end);
printf("\nLine-%d: %s\n", line, str);
fclose(fd);
}
All i need is to know how to do this, in a simple program without the use of getline()
Thanks
Edit: I also don't want to download software to make this work
use fgets instead of getline.
#include <stdio.h>
int main(void){
int end, loop, line;
char str[512];
FILE *fd = fopen("data.txt", "r");
if (fd == NULL) {
printf("Failed to open file\n");
return -1;
}
printf("Enter the line number to read : ");
scanf("%d", &line);
for(end = loop = 0;loop<line;++loop){
if(0==fgets(str, sizeof(str), fd)){//include '\n'
end = 1;//can't input (EOF)
break;
}
}
if(!end)
printf("\nLine-%d: %s\n", line, str);
fclose(fd);
return 0;
}
You have wrote:
char *str = NULL;
and you used it without initializing:
getline(&str, &bytes, fd);
first you must initialize it:
char *str=(char*)malloc(SIZEOFSTR);
you can add this part in your program instead of your do-while loop. You will be using fscanf() whose arguments are the file pointer, specifier of data type and the variable you want to store.
printf("Enter the line number to read : ");
scanf("%d", &line);
while(line--) {
fscanf(fd,"%s",str);
}
printf("\nLine-%d:%s\n",line,str);
Related
I have this code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE* ptr = fopen("data.txt","r");
char filename[100];
if (ptr==NULL)
{
printf("no such file.");
return 0;
}
char buf[100];
while (fscanf(ptr,"%*s %*s %s ",buf)==1)
printf("%s\n", buf);
printf("Create a file \n");
scanf("%s", filename);
fptr2 = fopen(filename, "w");
if (fptr2 == NULL)
{
printf("Cannot open file %s \n", filename);
exit(0);
}
c = fgetc(fptr1);
while (c != EOF)
{
fputc(c, fptr2);
c = fgetc(fptr1);
}
printf("\nContents copied to %s", filename);
fclose(fptr1);
fclose(fptr2);
return 0;
}
}
It coppies full content from one file to another. I need to copy only strings that have 5 as the last character (3 column)
For example Data.txt looks like that:
Alex 10B 4
John 10A 3
Kate 10C 5
In file that I will create during execution has to be coppied only Kate 10C 5 string. I've been trying for hours but I don't know how to do this. Can you help me?
In the end of each line there is a newline character, (\n) you can use that to read line by line and copy only the ones that you want:
FILE* dest = fopen("out.txt", "w+"); // supressed null check for simplicity
char buf[100];
char* char_to_find;
// parse line by line
while (fscanf(ptr, " %99[^\n]", buf) == 1){
char_to_find = buf;
// reach the end of the line
while(*char_to_find){
char_to_find++;
}
//move one back
char_to_find--;
// if it's 5 save, if not move on
if(*char_to_find == '5' && *(char_to_find - 1) == ' '){
fputs(buf, dest);
}
}
Live demo
The problem is that the function call
while (fscanf(ptr,"%*s %*s %s ",buf)==1)
consumes the input from the input stream, so that it is no longer available for copying. You are only saving the contents of the last field, but all other data is lost.
I suggest that you read one line at a time into a memory buffer, by calling the function fgets in a loop. That way, you will process one line of input per loop iteration, and will be saving the contents of the entire line.
In every loop iteration, you can use sscanf on this memory buffer to determine whether the third field has the desired value, and if it does, then you copy the entire line to the output file. Otherwise, you do nothing and proceed to the next line (i.e. the next loop iteration).
char line[100];
//process one line of input per loop iteration
while ( fgets( line, sizeof line, input_file ) != NULL )
{
char third_field[20];
if (
//third field was successfully extracted
sscanf( line, "%*s%*s%19s", third_field ) == 1
&&
//third field contains the string "5"
strcmp( third_field, "5" ) == 0
)
{
//copy entire line to output file
fputs( line, output_file );
}
}
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE* ptr = fopen("data.txt","r");
char filename[100];
if (ptr==NULL)
{
printf("no such file.");
return 0;
}
printf("Create a file \n");
scanf("%s", filename);
FILE* dest = fopen(filename, "w+"); // check for null like above
char buf[100];
char* char_to_find;
while (fscanf(ptr,"%99[^\n] ", buf) == 1){
char_to_find = buf;
while(*char_to_find != 0){
char_to_find++;
}
char_to_find--;
if(*char_to_find == '5'){
printf("%s\n", buf); // test ptint
fputs(buf, dest);
}
}
}
I am working on a assignment:
Open a text file and print its contents in command window, ask the user to
replace the text from the text file to be written and save the text
file.
When I set the maximum character size to 256,it works but when I give 20 it doesn't. Is there a way to overcome this problem by printing the characters beyond the defined limit?
I have used fgets() function.
#include <stdio.h>
#include <string.h>
#define MAX 20
int main(){
FILE *fptr1, *fptr2;
int lno, linectr = 1;
char str[MAX],fname[MAX];
char newln[MAX], temp[] = "temp.txt";
printf("\n\n Replace a specific line in a text file with a new text :\n");
printf(" Input the file name to be opened : ");
fgets(fname, MAX, stdin);
fname[strlen(fname) - 1] = '\0';
fptr1 = fopen(fname, "r");
if (!fptr1)
{
printf("Unable to open the input file!!\n");
return 0;
}
fptr2 = fopen(temp, "w");
if (!fptr2)
{
printf("Unable to open a temporary file to write!!\n");
fclose(fptr1);
return 0;
}
printf(" Input the content of the new line : ");
fgets(newln, MAX, stdin);
fgets(str, MAX, stdin);
printf(" Input the line no you want to replace : ");
scanf("%d", &lno);
lno++;
while (!feof(fptr1))
{
strcpy(str, "\0");
fgets(str, MAX, fptr1);
if (!feof(fptr1))
{
linectr++;
if (linectr != lno)
{
fprintf(fptr2, "%s", str);
}
else
{
fprintf(fptr2, "%s", newln);
}
}
}
fclose(fptr1);
fclose(fptr2);
remove(fname);
rename(temp, fname);
printf(" Replacement did successfully\n");
return 0;
}
I'm assuming you are asking how to read a 100 char long line into a 20 char sized buffer.
Well, obviously the whole line does not fit into the buffer. You need to read in chunks. You know you've read the last chunk when the buffer contains a newline (or EOF is reached)...
if (!fgets(str, MAX, fptr1)) /* EOF detected */;
//let's see if we got a partial line
size_t len = strlen(str); // note: len != 0 for text files
if (str[len - 1] == '\n') {
// full line
// do the comparison or whatever
} else {
// fgets got first chunk
// read rest of line and ignore it
for (;;) {
int ch = fgetc(fptr1);
if (ch == EOF) /* EOF detected */;
if (ch == '\n') break; // full line read, ready for next one
}
}
My program loads/saves double value into a text file using union.
I think I am having a buffer overflow, when I use fflush(stdin) it works, but I can't. The problem maybe somewhere else though. The code jumps without letting me enter a file to load from ( 2.000000 is autoinserted ).
Ps. Yes I know that tab[i] would be better than *(tab+i) but spare me, I just have to do it like this.
output :
Enter double value:8794.061758
Enter path to file you wish to save:valleykingstopwantreachspellshipcontinue
File saved
Enter a path to file you wish to load: 2.000000 ----- This value is inserted automatically ( I didnt write it)
Process finished with exit code 0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
union double_to_char_t
{
double d;
char bytes[8];
};
int save_double(const union double_to_char_t *dtc, const char *filename)
{
if(dtc == NULL || filename == NULL) return 1;
FILE * f=fopen(filename,"w");
if(f == NULL) return 2;
int result = fwrite(dtc, sizeof(dtc), 1, f);
if( result != 1)
{
fclose(f);
return 3;
}
fclose(f);
return 0;
}
int load_double(union double_to_char_t *dtc, const char *filename)
{
if( dtc == NULL || filename == NULL) return 1;
FILE * f = fopen(filename,"r");
if( f == NULL ) return 2;
int result = fread(dtc, sizeof(dtc), 1, f);
if( result != 1)
{
fclose(f);
return 3;
}
fclose(f);
return 0;
}
int main()
{
union double_to_char_t unia;
char temp1[40] = {0};
char temp2[40] = {0};
char *input1 = temp1;
char *input2 = temp2;
printf("Enter double value: ");
if(scanf(" %lf",&(unia.d))!=1)
{
printf("Incorrect input");
exit(1);
}
printf("Enter path to file you wish to save:");
fgets(input1, 40, stdin);
int wynik = save_double(&unia,input1);
if(wynik > 0)
{
printf("Couldn't create file\n");
exit(5);
}
else
{
printf("File saved\n");
}
printf("Enter a path to file you wish to load: ");
fgets(input2, 40, stdin);
// scanf(" %39[^\n]", input2);
int score = load_double(&unia,input2);
if(score > 0 && score < 3)
{
printf("Couldn't open file\n");
exit(4);
}
if(score == 3)
{
printf("File corrupted\n");
exit(6);
}
printf("%f",unia.d);
return 0;
}
You used %39[^\n] to read the filename, then typed a 40 character filename. The first 39 characters were put into input1, and the last character was left in the input stream.
When you then tried to get the filename for input2, it read that last character. That's why it didn't wait for you to type anything -- there was still input available after the first filename was read.
So you saved to valleykingstopwantreachspellshipcontinu and loaded from e.
You need to ensure that your input buffer is longer than any potential input. If you use fgets() instead of scanf(), you can test whether the input ends with a newline. If not, you can report that the input was too long, read characters until the newline, then ask for input again. (The non-standard fflush(stdin) discards everything up to the next newline, which is why adding that fixed the problem.)
if (!fgets(input1, 40, stdin)) {
printf("input error\n");
exit(1);
}
if (input1[strlen(input1)-1] != '\n') { // check for trailing newline
printf("filename too long\n);
exit(3);
}
input1[strlen(input1)-1] = '\0'; // remove it before using as filename
You could also use the getline() function. This isn't standard C, but it's POSIX and widely implemented. It allocates the input buffer dynamically so any length can be accomodated.
int main()
{
FILE *infile;
FILE *infile2;
char input[255],input2[255];
int status1, status2;
infile = fopen("test.txt", "r");
infile2 = fopen("test2.txt", "r");
if(infile == NULL)
{
printf("Can not open file 1!\n");
}
else if(infile2 == NULL)
{
printf("Can not open file 2!\n");
}
else
{
do
{
status1 = fscanf(infile, "%s", &input);
status2 = fscanf(infile2, "%s", &input2);
printf("File 1: %s\n File 2: %s\n", input, input2);
}while(status1 != -1 || status2 != -1);
}
fclose(infile);
fclose(infile2);
return 0;
}
My output looks like this:
Output
I would like to print out file 1 in one line not word by word. The same goes for file2. I'm kinda new to C so I'm stuck.
If you would like to read the entire line, use fgets function instead of fscanf:
char *status1, *status2;
.
.
.
do {
status1 = fgets(input, sizeof(input), infile);
status2 = fgets(input2, sizeof(input2), infile2);
printf("File 1: %s File 2: %s", input, input2);
} while (status1 || status2);
Note how printf no longer uses \n. This is because fgets keeps \n from the file inside your input string.
I made the changes to the code and it works, but another question. If i wanted to compare the files and write out the differnce to a new file like this:
File1: My name is Knut
File2: My name is KnutAndre
File3: Andre (This is the differnce between the files).
My teacher told me to use strcmp and then get the output into a new file, but i dont quite understand him.. Does anyone have some tips that i could try out?
This is how my code look so far:
int main()
{
FILE *infile;
FILE *infile2;
FILE *outfile3;
char input[255],input2[255];
char status1, status2;
infile = fopen("test.txt", "r");
infile2 = fopen("test2.txt", "r");
if(infile == NULL)
{
printf("Can not open file 1!\n");
}
else if(infile2 == NULL)
{
printf("Can not open file 2!\n");
}
else
{
do
{
status1 = fgets(input, sizeof(input), infile);
status2 = fgets(input2, sizeof(input2), infile2);
if(status1 != 0){
printf("File 1: %s\n\nFile 2: %s\n\n", input, input2);
int result = strcmp(input, input2);
printf("\nResult = %d\n\n", result);
}
}
while(status1 || status2);
}
fclose(infile);
fclose(infile2);
return 0;
}
When you are using the fscanf it will only read the characters until the non white space character occurs. When you need to get the input as whole line then you have to use fgets().
From the man page of fgets().
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an
EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte ('\0') is stored after the last character
in the buffer.
So you have to use like this.
fgets(input,255,infile);
fgets(input2,255,infile2);
While checking condition,
while(input != NULL || input2 != NULL);
In my school, we make a get_next_line function, who takes a file descriptor and a pointer to a string in parameter.
you can take a look here : https://github.com/juschaef/libtowel/search?utf8=%E2%9C%93&q=get+next+line
Glad to ask you again!
I want to create a program that basically reads a file called message.txt which would have some texts with a message, let's say: ''Hello I am a program'' and then encrypts that message and puts it in a file called encryptMessage.txt, additionally it will save the key used for the user in the file key.txt. Now this is what I have done so far. I don't know how to make the program read the file message.txt, show it into the screen and then encrypt it into the file. Any piece of advice? Thank you!
I was planning to use fscanf, but I can't use it because it's a line, not just a single string.
Please, if possible write the code yourself so I can compare it to what I have written so far. I always appreciate your feedback, thanks!
#include <stdio.h>
#include <ctype.h>
#define MAXSIZE 100
int main(void)
{
FILE *message;
FILE *encryptMessage;
FILE *key;
message = fopen("message.txt", "r");
encryptMessage = fopen("encryptMessage.txt", "w");
key = fopen("key.txt", "w");
if ((encryptMessage == NULL) || (encryptMessage == NULL) || (encryptMessage == NULL))
{
printf("Error reading file!!!\n");
return 1;
}
int userKey;
char sentence[MAXSIZE];
char q[MAXSIZE];
int i = 0;
printf("Input the text that you want to encrypt:\n> "); // These two lines are a test to see if I was able to encrypt the message, but this is not necessary. It should directly read the file called message.txt.
fgets(sentence, 99, stdin);
// printf("\nThe string that you wrote is:\n%s\n\n", sentence);
printf("Input the key:\n");
scanf("%d", &userKey);
fprintf(key, "%d", userKey);
//printf("\nThe key that you selected is: %d\n\n", userKey);
for(i = 0; sentence[i] != '\0'; ++i)
{
if( ( isupper(sentence[i]) ) || ( islower(sentence[i]) ) )
{
q[i] = sentence[i] + (char)userKey;
}
else
{
q[i] = (sentence[i]);
}
}
q[i] = '\0';
printf("%s", q);
fprintf(encryptMessage, "%s", q);
fclose(encryptMessage);
return 0;
}
To read a line from message.txt you need to use fgets function.
fgets(sentence, 99, stdin);
The above fgets(which you have in your code) reads from the stdin which is normally the keyboard. To make it read from the text file,use
fgets(sentence, MAX_SIZE, message);
Note the change in the second argument too. If you want to display whatever was scanned,uncomment the below line which you have in your code
//printf("\nThe string that you wrote is:\n%s\n\n", sentence);
Don't forget to close(using fclose) all the FILE pointers which you had opened(using fopen) after its use.