C Random, having problems - c

void getS(char *fileName){
FILE *src;
if((src = fopen(fileName, "r")) == NULL){
printf("%s %s %s", "Cannot open file ", fileName, ". The program is now ending.");
exit(-1);
}
//char *get = " ";
int c = 1;
char ch = 'x';
while(ch!=EOF) {
ch = fgetc(src);
if(ch == '\n') c++;
}
fseek(src, 0, SEEK_SET);
int random = rand() % c;
int i = 0;
for(i = 0; i < random; i++){
while(ch != '\n'){
ch = fgetc(src);
}
}
do{
ch = fgetc(src);
if(ch != '\n' && ch != EOF){
printf("%c", ch);
}
}while(ch != '\n' && ch != EOF);
printf("%c", '\n');
fclose(src);
}
So this is my function that grabs a file and prints out a random word in the file if each word is separated by a new line.
Question 1:
Why is the random having preference to the first 2 words?
Question 2: How would I make it so I can use this function multiple times without doing the printf("%c", '\n'); because if I don't have that in the end the previous function call just overwrites the old one.
Thanks in advance, I've been asking a bit today thanks for all the help stackoverflow! :)
P.S. using srand(time(NULL));

Look at the logic here:
for(i = 0; i < random; i++){
while(ch != '\n'){
ch = fgetc(src);
}
}
Once you hit a newline, you won't read any more characters, so you're always going to print either the first or second line.
You can fix it like this:
for(i = 0; i < random; i++){
ch = fgetc(src); // start by reading the first character on the line
while(ch != '\n'){
ch = fgetc(src);
}
}
Jim Balter also notes that ch would best be declared as an int. This is because EOF is not considered to be a regular character.

without printf("%c","\n"); line at the end it is working fine...

Related

Why the functions doesn't return new line with replaceable keywords?

Hey just doing some exercises in c, one is saying to replace tabs in the input string with any other characters , i restrict myself to only using getchar(), no gets() fgets() etc..., as my learning book didn't catch it yet, so i tried to not break the flow, the code below just printf() the same line it receives, can you please examine why ?
#include <stdio.h>
int main(){
char line[20];
char c;
int i = 0;
printf("Enter name: ");
while ( c != '\n'){
c = getchar();
line[i] = c;
++i;}
while (line[i] != '\0')
if (line[i] == '\t')
line[i] = '*';
printf("Line is %s \n", line);
return 0;}
c, which is used in c != '\n', is not initialized at first. Its initial value is indeterminate and using is value without initializng invokes undefined behavior.
You are checking line[i] != '\0', but you never assigned '\0' to line unless '\0' is read from the stream.
You should initialize i before the second loop and update i during the second loop.
Return values of getchar() should be assigned to int to distinguish between EOF and an valid character.
You should perform index check not to cause buffer overrun.
Fixed code:
#include <stdio.h>
#define BUFFER_SIZE 20
int main(){
char line[BUFFER_SIZE];
int c = 0;
int i = 0;
printf("Enter name: ");
while ( i + 1 < BUFFER_SIZE && c != '\n'){
c = getchar();
if (c == EOF) break;
line[i] = c;
++i;
}
line[i] = '\0';
i = 0;
while (line[i] != '\0'){
if (line[i] == '\t')
line[i] = '*';
++i;
}
printf("Line is %s \n", line);
return 0;
}

Counting the number of characters, words and number of lines present in a text input such that it takes input until user types the word 'END'

I have written code for this. But the problem I am facing is that my program doesn't takes more input after I wrote any of one letters of word END. I want it to stop only when it encounters the word END, not only single letter. The code that I have tried is below:
#include<stdio.h>
void main(){
char ch[100];
int nl = 0, nw = 0, nc = 0;
printf("Enter lines of text (enter END to complete)\n");
scanf("%[^END]", ch);
for(int i = 0; ch[i] != '\0'; i++){
if(ch[i] == '\n'){
nl++;
nw++;
}
else if(ch[i] == ' ' || ch[i] == '\t'){
nw++;
nc++;
}
else{
nc++;
}
}
printf("Character = %d, Words = %d, Lines = %d\n", nc, nw, nl);
}
How can I achieve my goal?
Problem is in this line scanf("%[^'END']", ch);, you can't do this in scanf %[^'END'].
Rather you can ask the user to input EOF character instead of "END" and then you can put that EOF into condition to terminate the process.
Take a look at this code:
#include<stdio.h>
int main(void)
{
char c;
int nl = 0, nw = 0, nc = 0;
printf("Enter text (enter EOF to complete)\n>");
while( (c = getchar()) != EOF)
{
if(c == '\n') // If C has a newline character then it means there's a new line in text.
nl++;
if(c == ' ' || c == '.') // We are assuming that these characters can be delimiters b/w words.
nw++;
nc++; // Every Input is a character.
}
printf("Character = %d, Words = %d, Lines = %d\n", nc, nw, nl);
return 0;
}
NOTE: There could be problems with this code while deciding no. of words. But if input isn't that complex. It'll not give any logical error. You can advance it to get the accurate no. of words from input. Most of the words in a paragraph are separated by ., , or _.
If you really want to go with the "END" word, try this code:
#include <string.h>
#include <stdio.h>
#define BUFFER_SIZE 1000
int main(void)
{
char input[BUFFER_SIZE] = {'\0'}, *cptr = NULL;
int word_count = 0, line_count = 0, char_count = 0, i = 0;
printf("Input text\nInput END to terminate>\n");
do
{
scanf("%c", &input[i]);
i++;
cptr = strstr(input, "END");
}
while(cptr == NULL);
char_count = i - 3; // Excluding END word.
for( ; i != 0; i--)
{
if(input[i] == '\n') // If C has a newline character then it means there's a new line in text.
line_count++;
if(input[i] == ' ' || input[i] == '.') // We are assuming that these characters can be delimiters b/w words.
word_count++;
}
printf("Character = %d, Words = %d, Lines = %d\n", char_count, word_count, line_count);
return 0;
}

My program is not accepting simple string in c using getchar

int count0=0,count1=0,cnt=0;
char str[200];
char ch;
ch= getchar();
while(ch!='\0')
{
str[cnt]=ch;
cnt++;
}
str[cnt]='\0';
printf("%s",str);
output expected :
shubham
output:
Your code didn't print anything.
input:
shubham
You are just accepting one character, you should replace while() with do-while().
int ch;
do
{
ch= getchar();
if(ch == EOF)
{
str[cnt] = '\0';
break;
}
else
str[cnt] = ch;
cnt++;
}while(ch != '\0');
The above loop should fix the issue that you are facing. You need to enter NULL terminator using ctrl+# at the end of the string.
A while loop is fine. Simply put the getchar() in it.
Use int ch rather than char ch as getchar() typically returns 1 of 257 different values: 0 - 255 and EOF(a negative value). EOF indicates end-of-file (or rare input error).
size_t count = 0;
int ch;
// test to insure not too many read, ch == EOF? ch == end-of-line?
// | | |
while (count < sizeof str - 1 && (ch == getchar()) != EOF && ch != '\n') {
str[count++] = ch;
}
str[count] = '\0';
puts(str);
Or perhaps one prefers a for() loop?
size_t count;
for (count = 0; count < sizeof str - 1; count++) {
int ch == getchar();
if (ch == EOF || ch == '\n') {
break;
}
buf[count] = ch;
}
buf[count] = '\0';
puts(str);
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int i=0, j=0,T;
T=getchar();
int ch;
for(i=0; i<T ;i++)
{
int cnt=0;
char str[200];
while ((ch = getchar()) != '\n' && ch != EOF)
{
str[cnt] = ch;
cnt++;
}
str[cnt]='\0';
printf("\n%s",str);
}
return 0;
}
**
here str is storing almost everything
space, \n,
**
expected output:
shubham
shubh
output:
shubham
shubh
shubham
shubh
input:
shubham
shubh
*/

Getc() reading \n improperly

I am creating a program that prints each line of a file one by one in reverse word order. i.e. "The big black moose" prints as "moose black big The".
However, in the code below, it does not print the last word of lines that do not have a delimiter before the line break. A delimiter in this case is defined as any whitespace character such as space or tab.
int main(int argc, char const *argv[]) {
if (argc != 2) return 0;
int i = 0, c;
int isD = 0, wasD = 1;
int count = 0;
FILE *file = fopen(argv[1], "r");
while ((c = getc(file)) != EOF) {
isD = c == ' ' || c == '\t' || c == '\n';
if (!isD) {
chars[i++] = c;
count++;
}
if (isD && !wasD) {
shiftInsert(i++, count);
count = 0;
}
wasD = isD;
}
fclose(file);
return 0;
}
int shiftInsert(int length, int shift) {
int word[shift+1], i;
printf("\n----------\nL:%d,S:%d\n", length, shift);
for (i = 0; i < shift; i++)
word[i] = chars[length-shift+i];
word[shift] = ' ';
for (i = 0; i < shift; i++)
printf("%c", word[i]);
for (i = length; i >= 0; i--)
chars[i+shift+1] = chars[i];
for (i = 0; i <= shift; i++)
chars[i] = word[i];
printf("|");
}
This happens, because you don't enter the loop when getc finds the end of the file. If wasD is false, you'll have one unprocessed word in the buffer.
You could treat EOF as whitespace and place the terminating condition at the end of the loop:
do {
c = getc(file);
isD = (c == ' ' || c == '\t' || c == '\n' || c == EOF);
// ...
} while (c != EOF);
This works, because you use the value of c only if it is not a delimiter. (The special value EOF is outside the valid range of (unsigned) chars and should not be inserted into strings or printed.)
stdout is not getting flushed because your last output didn't contain a newline...
Change this line
printf("|");
to
printf("|\n");

Transposition Cipher in C

I have been able to kind of get my transposition cipher to work a little bit. However, i am running into problems such as not being able to take in more than 5 characters in a text file. Currently my program is also not able to go to a new line when the encrypted text is outputted into a output file. I also am having trouble cycling my transposition cipher over and over again.
For example, if trans1.txt contained the text "JacksJacksJacks" all in one line it should print "csJakcsJakcsJak" all on the first line of the trans2.txt
Also the transposition cipher should reset every line. It should restart from position 2 then 4 then 0 etc... every time its a new line.
#include <stdio.h>
int c, j, i, k,p=0;
char transposition[]={2,4,0,1,3}, input[256];
int main(){
FILE *file1=fopen("trans1.txt", "r");
FILE *file2=fopen("trans2.txt", "w");
while(fgets(input,sizeof(input),file1)!=NULL){
for(i=0;i<5;i++){
k=transposition[i];
fprintf(file2,"%c",input[k]);
}
}
return 0;
}
#include <stdio.h>
int main(){
char transposition[]={2,4,0,1,3};
char input[256] = "JacksJacksJacks\n";
int len = sizeof(transposition);
char ch, temp[len];
int i, j, k;
j=i=0;
do {
for( ; '\0'!=(ch = input[i]) && ch != '\n';++i){
temp[j++] = ch;
if(j == len){
j=0;
++i;
break;
}
}
while(j!=0){
temp[j++] = '.';//pading if(i % len != 0)
if(j == len)
j = 0;
}
for(k=0;i && k<len;++k){
printf("%c", temp[transposition[k]]);
}
}while(ch != '\n' && ch != '\0');
printf("\n");
return 0;
}
another way for the same thing
i=0;
do {
for(j=0;j<len;++j){
ch = input[i];
if(ch != '\n' && ch != '\0'){
temp[j] = ch;
++i;
} else {
temp[j] = '.';
}
}
if(temp[0] != '.')
for(k=0;k<len;++k){
printf("%c", temp[transposition[k]]);
}
}while(ch != '\n' && ch != '\0');
printf("\n");
Some hints:
What happens after the for-loop processes 5 characters?
Your problem seems character oriented. Why not use getc()?
For extra credit:
What happens if, just for example, there were fewer than 5 characters on the 2nd line?

Resources