#include <Windows.h>
#include <cstdio>
const int KEY=111;
void encryptStrA(char* sometext)
{
int length;
length=strlen(sometext);
for(int i=0; i<length;i++)
sometext[i]^=KEY;
}
int main(void)
{
FILE* pFile=fopen("pliczek","wb");
char sign;
char sampleString[]="Hello world!";
encryptStrA(sampleString);
fprintf(pFile,"%c%c%s%c%c",13^KEY,10^KEY,sampleString,13^KEY,10^KEY);
fclose(pFile);
pFile=fopen("pliczek","rb");
while(!feof(pFile))
{
fscanf(pFile,"%c",&sign);
printf("%c",sign^KEY);
}
fclose(pFile);
system("PAUSE");
return 0;
}
I evaded some tricky things
File is opened in binary mode
In encryptStrA strlen function isn't placed directly in the loop condition
In spite of these, it still has been outputting "Hell" instead of "Hello World!"? More precisely, cuts everything after spotting the key character .What's the reason? I use OS in which every line of text is ended with carriage return(ASCII 13) and line feed (10).
The code fprintf("%s", s); expects s to be a zero-terminated string. When you reach 'o'^111 it gives a null character, so the rest of the string is not written to the file.
You can use fwrite instead.
Related
I need to read in words from a text file and then count the occurrences of each word but I can't figure out how to store the words in a variable.
I read the code in using fgets, and then i can print it using printf. However when I try to store the character array in a different array that I can use to compare the character arrays later, i keep getting seg faults. How can I go about saving the character array "line" in a different array?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXSIZE 500
#define MAXWORDS 1000
int main ( int argc, char *argv[] ) {
char line[MAXSIZE];
char line1[MAXWORDS][MAXSIZE];
int i,j,k;
int count = 0;
while ( fgets ( line, MAXSIZE, stdin ) != NULL ) {
printf("%s", line);
strcpy(line1[count], line);
printf("%s\n", line1[count][i]);
count++;
}
return(0);
}
(This is my updated code, it still prints the first line and then seg faults.)
when I compile and run this code, it prints the first line of the text file and then returns "segmentation fault"
Perhaps the question code is close.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXSIZE 500
#define MAXWORDS 1000
int main(int argc, char *argv[])
{
char line[MAXSIZE];
char line1[MAXWORDS][MAXSIZE];
int count = 0;
while(fgets(line, MAXSIZE, stdin))
{
printf("%s", line);
strcpy(line1[count], line);
printf("%s\n", line1[count]); // instead of: printf("%s\n", line1[count][i]);
count++;
}
return(0);
}
Your strcpy works as it should, but the printf caused a warning already at compile time, change the printf-line from printf("%s\n", line1[count]); to printf("%s\n", line1[count]);
After the while loop you can verify your copy with:
for (int i=0; i < count; i++){
printf("%d: %s",i, line[i]);
}
Although fgets will put a terminating 0-byte at the end of the buffer, it would be more defensive to user strncpy which is guaranteed not copy more than n-bytes, but in this example you could eliminate the copy altogether by writing directly in to line[count] buffer.
Also you shod take care and stop reading before overwriting your buffers.
When you call fgets you limit the read to MAXSIZE which is good but you should also check count is below MAXWORDS
I'm trying to read in inputs from the terminal, I want to stop reading inputs if there is a blank line and enter is pressed. Here is what I have at the moment.
#include <stdio.h>
#include <string.h>
int main(int argc,char const *argv[]){
char input[1024];
while(fgets(input,1024,stdin)!=NULL){
printf("%s", input);
}
if(EOF){
printf("EOF");
}
return 0;
}
One easy thing that you could do is to check the length of the string read in by fgets. The newline character at the end of the input string is considered a valid character by fgets. That means that the length of the string you're testing would be 1 if you just entered a newline So, you want to move the test inside the loop instead of trying to test for EOF outside of the loop. So, your code should look like this:
#include <stdio.h>
#include <string.h>
int main(void) {
char input[1024];
while(fgets(input,1024,stdin)!=NULL) {
printf("%s", input);
if(strlen(input) == 1) {
printf("EOF\n");
break;
}
}
return 0;
}
Also note, to get the EOF test to work you wouldn't hit enter, instead you'd send the end of file key, like CTRL-D on linux to your program. In this case you wouldn't have a strlen test inside the loop.
My file contains three lines, after using fgets to read the file into an array, I want to break the three lines at the new line character and print the three lines separately out on the console and if possible store the three lines in three different arrays.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
FILE *infile;
char data[BUFSIZ],*pa,token_seperator[]={"\n"};
infile=fopen("example","r");
while((fgets(data,BUFSIZ,infile)!=NULL))
pa=strtok(data,token_seperator);
while(pa!=NULL)
{
printf("%s\n",pa);
pa=strtok(NULL,token_seperator);
}
}
There is no any sense "to break the three lines at the new line character" because a line can contain no more than one new line character.
If you need to read each line in a separate array then just declare a two-dimensional character array. If you want you can remove the new line character appended to each line by the call of fgets.
So the program can look the following way.
#include <stdio.h>
#include <string.h>
#define N 3
int main( void )
{
FILE *infile;
char data[N][BUFSIZ];
infile = fopen( "example", "r" );
if ( infile )
{
size_t n = 0;
for (; n < N && fgets(data[n], BUFSIZ, infile); n++)
{
data[n][strcspn(data[n], "\n")] = '\0';
}
for (size_t i = 0; i < n; i++)
{
printf("%s\n", data[i]);
}
}
return 0;
}
The function below,truncCrLf, deletes from ASCII-0 strings the first occurence of the CR and/or LF codes. This is what you are looking for because the fgets function reads from the file till these ASCII codes (0xA and/or 0xD).
This function acts under both Linux and Windows SO.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * truncCrLf(char *data)
{
char *app=NULL;
app = strchr(data, '\n');
if (app)
*app=0;
app = strchr(data, '\r');
if (app)
*app=0;
return data;
}
int main(void)
{
char test[200];
strcpy(test,"Hello world\n");
printf("%s......\n",test);
truncCrLf(test);
printf("%s......\n",test);
return 0;
}
You will need allocate some memory to do this, just because you don't know how many line you finally will have nor the size of each one.
I suggest you the next code
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef SplittedString char[BUFSIZ]
int main()
{
FILE *infile;
char token_seperator[]={"\n"};
SplittedString data;
SplittedString myLines[50]; // you can modify this number to hold more lines
int i=0;
infile=fopen("example","r");
while((fgets(data,BUFSIZ,infile)!=NULL) && i < 50){ //prevent array overflow
printf("%s\n",data);
strcpy(myLines[i], data);
++i;
}
}
I have a program that has a text file that is variable in length. It must be capable of being printed in the terminal. My problem is that if the code is too large, part of it becomes inaccessible due to the limited scroll of terminal. I was thinking of having a command executed by a character to continue the lines after a certain point, allowing the user to see what they needed, and scroll if they needed. However the closest I have come is what you see here, which prints the text file one line at a time as you press enter. This is extremely slow and cumbersome. Is there another solution?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main()
{
FILE *audit;
audit = fopen("checkout_audit.txt", "r");
char length_of_code[60000];
int ch;
while ((ch = fgetc(audit)) != EOF)
{
fgets(length_of_code, sizeof length_of_code, audit);
fprintf(stdout, length_of_code, audit);
getch();
if (ferror(audit))
{
printf("This is an error message!");
return 13;
}
}
fclose(audit);
return 0;
}
The libraries are included as I tried various methods. Perhaps there is something obvious I am missing, however after looking around I found nothing that suited my needs in C.
You can keep a count of something like num_of_lines and keep incrementing it and when it reaches some number(say 20 lines) then do a getchar() instead of doing it for each line.
Make sure you don't use feof() as already suggested. Just for the purpose of how it can be done I am showing the below snippet.
int num_of_lines = 0;
while(!feof(fp))
{
// fgets();
num_of_lines++;
if(num_of_lines == 20)
{
num_of_lines = 0;
getch();
}
}
Putting the same thing in your code:
int main()
{
FILE *audit;
audit = fopen("checkout_audit.txt", "r");
char length_of_code[60000];
int num_of_lines = 0;
int ch;
while (fgets(length_of_code, sizeof length_of_code, audit) != NULL)
{
fprintf(stdout, length_of_code, audit);
if (ferror(audit))
{
printf("This is an error message!");
return 13;
}
num_of_lines++;
if(num_of_lines == 20)
{
num_of_lines = 0;
getch();
}
}
fclose(audit);
return 0;
}
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 is stored after the last character in the buffer.
So char length_of_code[60000]; is not a better option.
Try to set the size of array to optimum value which in most case is 80.
Also as fgets fetches line by line you will have to output line by line untill EOF
EDIT:
1. 2nd argument to fprintf should be the format specifier and not length
2. 3rd arg should be a string and not the file pointer
fprintf(stdout, "%s", length_of_code);
Code Snippet:
while (fgets(length_of_code, sizeof(length_of_code), audit))
{
fprintf(stdout, "%s", length_of_code);
getch();
if (ferror(audit))
{
printf("This is an error message!");
return 13;
}
}
Im doing a railroad cipher (zigzag cipher) however you may call it, I finally seemed to get my code to work properly and I got it to print the correct output, but unfortunately my teacher calls for the output to be printed 80 columns wide (80 characters per line). Unfortunately, the way my encryption is set up I can not find a way to do this since I set my encryption "rail by rail".
For the assignment we must read in the file, and strip it of all spaces and special characters, and to make all uppercase letters lower-case. Then encrypt the message. My issue is the printing portion in the encrypt function.
since its ran from command line here are the files i used
the first file pointer is for the rails, sample would be: 9
second file pointer is the text, sample i used is:
We shall not flag or fail. We shall go on to the end. We shall fight in France, we
shall fight on the seas and oceans, we shall fight with growing confidence and
growing strength in the air, we shall defend our island, whatever the cost may be, we
shall fight on the beaches, we shall fight on the landing grounds, we shall fight in
the fields and in the streets, we shall fight in the hills. we shall never surrender!
my output is correct according to my teachers output, but unfortunately i get 30% off for not having it 80 characters per line... this is due in a few hours but I can't seem to figure it out. Any help is greatly appreciated.
I would show the output for reference but I don't know how to copy and paste from the command line, and it only runs from there.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
# define MAX 10000
void condense(char* str)
{
int original=0;
int newplace =0;
while (str[original] != '\0')
{
if(isalpha(str[original] ))
{
str[newplace]= tolower(str[original]);
++newplace;
}
++original;
}
str[newplace] = '\0';
}
char * deblank(char *str)
{
char *out = str, *put = str;
for(; *str != '\0'; ++str)
{
if(*str != ' ')
*put++ = *str;
}
*put = '\0';
return out;
}
void encrypt(int rail,char *plain)
{
char railfence[rail][MAX],buf[2];
int i;
int number=0,increment=1;
buf[1]='\0';
for(i=0;i<rail;i++)
railfence[i][0]='\0';
for(i=0;i<strlen(plain);i++)
{
if(number+increment==rail)
increment=-1;
else if(number+increment==-1)
increment=1;
buf[0]=plain[i];
strcat(railfence[number],buf);
number+=increment;
}
for(i=0;i<rail;i++)
printf("%s",railfence[i]);
}
int main(int argc, char *argv[])
{
int rail,mode;
char text[MAX];
FILE* fp1;
FILE* fp2;
fp1 = fopen(argv[1], "r");
fp2 = fopen(argv[2], "r");
int key;
fscanf(fp1, "%d", &key);
printf("key is %d", key);
char c;
int index = 0;
fgets(text, 10000, fp2);
printf("%s \n", text);
// text[index] = '0';
char nospace[MAX];
deblank(text);
printf("text deblanked: %s \n", text);
//printf("%s", deblank(text));
condense(text);
printf("\nthe text condensed is: %s", text);
printf("\n the text encrypted is \n");
encrypt(key,text);
return 0;
}
Simple. Instead of printing each rail as a whole, print each rail character by character, and count. In the example below I assume your instructor's 80 characters per line is 79 characters of ciphertext plus one newline character. I do not know whether you are expected to print a newline at the end of the ciphertext, but if so just add printf("\n"); at the end of encrypt (though you might want to check that there was at least one character of ciphertext before doing so).
void encrypt(int rail,char *plain)
{
char railfence[rail][MAX],buf[2];
int i, col = 0, j, len; // added col, j, and len
int number=0,increment=1;
buf[1]='\0';
for(i=0;i<rail;i++)
railfence[i][0]='\0';
for(i=0;i<strlen(plain);i++)
{
if(number+increment==rail)
increment=-1;
else if(number+increment==-1)
increment=1;
buf[0]=plain[i];
strcat(railfence[number],buf);
number+=increment;
}
for(i=0;i<rail;i++)
{
len = strlen(railfence[i]); // get the length of the rail
for(j=0;j<len;++j) // for each char in the rail
{
printf("%c", railfence[i][j]);
if (++col==79) {
col = 0;
printf("\n");
}
}
}
}
Other than that, I thoroughly recommend using more whitespace in your formatting, as well as checking things like whether the user passes in two arguments or not, whether your files were opened successfully or not, and also remembering to close any files you open.
As result, your program is hard to read, and currently behaves badly if I do not provide both command line arguments or if I give it non-existent files.