C Program file-io user input - c

This program takes a a file name which contains a particular sentence and shifts by a certain amount.
if I have Hello and shift by 22 it should be Dahhk, This worked properly when I didn't enter the file name and had the file name in the program manually like
ifp = fopen( "input.txt", "r" );
However when I have the user enter the file name and the input is Hello and shift by 22 the output becomes D{‚‚…
ifp = fopen( name, "r" );
I tried using scanf("%s", name);
and I tried using fgets(name, sizeof(name), stdin);
both produce the same results
I am not sure how to fix this issue.
#include <stdio.h>
#define MAX_LEN 100
void decode( char *sentence, int shift );
int main( void )
{
FILE *ifp;
FILE *ofp;
char str[MAX_LEN];
int shift_by = 0;
char name[100];
printf("Program name: \n");
scanf("%s", name);
printf( "Please enter shift by and press enter\n" );
scanf( " %d", &shift_by );
ifp = fopen( name, "r" );
ofp = fopen( "output.txt", "w" );
if ( ifp == NULL )
{
printf( "FILE doesnt open" );
return 1;
}
while ( fgets( str, MAX_LEN, ifp ) != NULL )
{
decode( str, shift_by );
fprintf( ofp, " %s", str );
}
fclose( ifp );
fclose( ofp );
return 0;
}
void decode( char *sentence, int shift )
{
int i = 0;
char p;
while ( p = sentence[i] )
{
if ( ( p >= 'a' ) && ( p <= 'z' ) )
{
p = ( p - 'a' ) + shift % 26 + 'a';
}
if ( ( p >= 'A' ) && ( p <= 'Z' ) )
{
p = ( p - 'A' + shift ) % 26 + 'A';
}
sentence[i] = p;
i++;
}
}

OP's code has a small error:
// p = ( p - 'a' ) + shift % 26 + 'a';
p = ( p - 'a' + shift) % 26 + 'a';
Curiously OP coded correctly with
p = ( p - 'A' + shift ) % 26 + 'A';
The hint was "Hello" --> "D{‚‚…" worked for uppercase, yet not lowercase.

Related

Cannot print or access char * inside a function

The code below does not print nor return the char * temp which I am trying to retrieve from a text file containing a matrix of the form:
4
spQ77377.1 0.000000 0.776030 0.781073 0.804880
spO91086.1 0.776030 0.000000 0.564157 0.559756
spP04578.2 0.781073 0.564157 0.000000 0.302724
spO12164.1 0.804880 0.559756 0.302724 0.000000
The whole code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char * const getField( char lineBuffer[255], int field ) {
printf( "\n " );
static char temp[30];
int f = 0;
for( int i = 0; lineBuffer[i]!='\n' ; i++ ) {
if( f == field && lineBuffer[i] != ' ' ) {
temp[i] = lineBuffer[i];
printf( "%c", temp[i] );
}
if( lineBuffer[i] == ' ' && lineBuffer[i+1] == ' ' ) {
printf( "||" );
f++;
}
if( f > field ) {
printf( " break " );
printf( "*%s*", temp );
fflush(stdout);
return temp;
}
}
return "!";
}
int main() {
FILE *matrixStream;
matrixStream = fopen( "outfile", "r" );
if ( matrixStream == NULL ) {
printf( "\n\tERROR FILE NOT FOUND!\n" );
exit( 1 );
}
char lineBuffer[255];
fseek( matrixStream, 0, SEEK_SET );
int line = 0;
char ** field1 = malloc( 4 * sizeof( char *) );
while( fgets( lineBuffer, 255, matrixStream ) ) {
if( line != 0 ) {
printf( "\n line = %d ", line-1 );
if( line == 1 ) {
field1[line-1] = malloc( 30 * sizeof( char ) );
strcpy( field1[line-1], getField( lineBuffer, 1 ) );
}
}
line++;
}
printf( "\n" );
fclose( matrixStream );
return 0;
}
My objective is to have the function getField() to return a certain field or column (provided in argument as int field) for a line in the matrix.
For now, I only have the following output and can not seem to understand the problem, there are no error message during compilation with the options -Wall -pedantic. Here is the exact output:
line = 0
||0.000000|| break **
line = 1
line = 2
line = 3
The value of char * temp is not printed between the * characters as it should be.
Thank you in advance for any help or advice you can provide.
you need to terminate your temp buffer, and to have 2 indexes
static char temp[30];
int toff = 0; // temp offset
int f = 0;
for( int i = 0; lineBuffer[i]!='\n' ; i++ ) {
if( f == field && lineBuffer[i] != ' ' ) {
temp[toff++] = lineBuffer[i]; // use temp offset
printf( "%c", temp[i] );
}
if( lineBuffer[i] == ' ' && lineBuffer[i+1] == ' ' ) {
printf( "||" );
f++;
}
if( f > field ) {
temp[toff] = 0; // 0 terminate
printf( " break " );
printf( "*%s*", temp );
fflush(stdout);
return temp;
}
}
of course you should also error out if toff > sizeof(temp)
BTW the reason you get nothing is that temp, being static, is initialized to 0 at startup and you never write anything to temp[0] (beacuse you use the line buffer offset). So temp is an empty string always

C: outputs the total number of times the first word occurs

when I enter a sentence, this code should get the first word and count the how many times repeated.
firstWord(): This function gets the string as a parameter. Then, outputs the total number of times the first word occurs.
(this code consisting of 4 functions and in this func(firstWord()) I should use 'string' as a parameter, in main function I just call the firstWord func. )
number of times the first word occurs.
for ex: sentence is no changes and no suprises
first word no repeated 2 times.
here is the code.
void firstWord(char st3[]){
char firstw[20];
char *ptr;
int i=0;
int count=0;
ptr=strstr(st3,firstw);
while (ptr = '\0')
{
count++;
ptr++;
ptr = strstr(ptr, firstw);
}
printf("First word %s is repeated %d times\n", firstw, count);
}
The function does not make a sense.
You are using the uninitialized array firstw in a call of strtsr as for example
char firstw[20];
//..
ptr=strstr(st3,firstw);
that invokes undefined behavior.
Also there is a typo in the condition of the while statement
while (ptr = '\0')
Instead of using the equality operator == you are using the assignment operator = after which the pointer ptr becomes a null pointer.
At first you need to find the first word in the source string and then count how many times it is present in the source string.
Pay attention to that the function strstr can find a substring that does not form a word that is that is not delimited by white space characters.
Also at least the parameter of the function firstWord should be declared with the qualifier const because the source string is not changed within the function. And the return type of the function should not be void. The function should return the counter and the position and the length pf the first word in the source string as for example by using an object of a structure type.
The function can be implemented for example the following way as shown in the demonstration program below.
#include <stdio.h>
#include <string.h>
struct Word
{
char *pos;
size_t length;
size_t counter;
};
struct Word firstWord( const char *s )
{
const char *delim = " \t\n";
struct Word word = { .pos = NULL, .length = 0, .counter = 0 };
while ( *s )
{
s += strspn( s, delim );
if ( *s )
{
size_t n = strcspn( s, delim );
if ( word.pos == NULL )
{
word.pos = ( char * )s;
word.length = n;
word.counter = 1;
}
else
{
if ( n == word.length && strncmp( word.pos, s, n ) == 0 )
{
++word.counter;
}
}
s += n;
}
}
return word;
}
int main( void )
{
const char *s = " A AB A ABC A";
struct Word word = firstWord( s );
if ( word.pos != NULL )
{
printf( "The first word \"%.*s\" is found %zu time(s)\n",
word.length, word.pos, word.counter );
}
}
The program output is
The first word "A" is found 3 time(s)
Using that function you can for example sort an array of strings in the lexicographical order of first words and if the words are equal in the ascending order of their counters in strings.
Here is a demonstration program.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Word
{
char *pos;
size_t length;
size_t counter;
};
struct Word firstWord( const char *s )
{
const char *delim = " \t\n";
struct Word word = { .pos = NULL, .length = 0, .counter = 0 };
while ( *s )
{
s += strspn( s, delim );
if ( *s )
{
size_t n = strcspn( s, delim );
if ( word.pos == NULL )
{
word.pos = ( char * )s;
word.length = n;
word.counter = 1;
}
else
{
if ( n == word.length && strncmp( word.pos, s, n ) == 0 )
{
++word.counter;
}
}
s += n;
}
}
return word;
}
int cmp( const void *a, const void *b )
{
const char *s1 = *( const char * const * )a;
const char *s2 = *( const char * const * )b;
struct Word word1 = firstWord( s1 );
struct Word word2 = firstWord( s2 );
size_t n = word1.length;
if ( word2.length < n ) n = word2.length;
int result = strncmp( word1.pos, word2.pos, n );
if ( result == 0 )
{
result = ( word2.length < word1.length ) - ( word1.length < word2.length );
if ( result == 0 )
{
result = ( word2.counter < word1.counter ) - ( word1.counter < word2.counter );
}
}
return result;
}
int main( void )
{
const char * s[] =
{
"CCC CCC CCC",
"CCC CCC",
"BB BB",
"A A",
"CC",
"BB",
"CCC",
"A"
};
const size_t N = sizeof( s ) / sizeof( *s );
for ( size_t i = 0; i < N; i++ )
{
puts( s[i]);
}
putchar( '\n' );
qsort( s, N, sizeof( const char * ), cmp );
for ( size_t i = 0; i < N; i++ )
{
puts( s[i]);
}
putchar( '\n' );
}
The program output is
CCC CCC CCC
CCC CCC
BB BB
A A
CC
BB
CCC
A
A
A A
BB
BB BB
CC
CCC
CCC CCC
CCC CCC CCC
If you need to write a function that just determines the first word in a string then it can look the following way as shown in the demonstration program below.
#include <stdio.h>
#include <string.h>
struct Word
{
char *pos;
size_t length;
};
struct Word firstWord( const char *s, const char *delim )
{
struct Word word = { .pos = NULL, .length = 0 };
while ( *s && word.pos == NULL )
{
s += strspn( s, delim );
if ( *s )
{
size_t n = strcspn( s, delim );
word.pos = ( char * )s;
word.length = n;
s += n;
}
}
if ( word.pos == NULL )
{
word.pos = ( char * )s;
}
return word;
}
int main( void )
{
const char *s = " A AB BA A";
struct Word word = firstWord( s, " \t\n" );
char first_word[word.length + 1];
strncpy( first_word, word.pos, word.length );
first_word[word.length] = '\0';
printf( "The first word is \"%s\" at position %zu\n",
first_word, word.pos - s );
}
The program output is
The first word is "A" at position 3
You don't consider that "cat can catch mice" should report only 1 occurrence of "cat".
Try this (or something like it):
void firstWord( char st3[] ) {
char *firstw = "EMPTY STRING";
int count = 0;
for( char *ptr = st3; ( ptr = strtok( ptr, " .,-" ) ) != NULL; ptr = NULL )
if( count == 0 ) {
firstw = ptr;
count++;
} else if( strcmp( ptr, firstw ) == 0 )
count++;
printf( "First word %s is repeated %d times\n", firstw, count );
}
Update
With the feedback "didn't work", I've added a few printf's to show that it does work...
void firstWord( char st3[] ) {
char *firstw = "EMPTY STRING";
int count = 0;
printf( "Using: '%s'\n", st3 );
for( char *ptr = st3; ( ptr = strtok( ptr, " .,-" ) ) != NULL; ptr = NULL )
if( count == 0 ) {
firstw = ptr;
count++;
} else if( strcmp( ptr, firstw ) == 0 )
count++;
printf( "First word %s occurs %d times\n\n", firstw, count );
free( st3 );
}
void my_main(void) {
firstWord( strdup( "cat can catch mice" ) );
firstWord( strdup( "cat cat catch cat" ) );
firstWord( strdup( " cat cat catch cat" ) );
firstWord( strdup( "dog dog dog dog dog" ) );
firstWord( strdup( "" ) );
}
Output:
Using: 'cat can catch mice'
First word cat occurs 1 times
Using: 'cat cat catch cat'
First word cat occurs 3 times
Using: ' cat cat catch cat'
First word cat occurs 3 times
Using: 'dog dog dog dog dog'
First word dog occurs 5 times
Using: ''
First word EMPTY STRING occurs 0 times

Code giving runtime error in codeforce prob 474 A

I am a beginner in codeforces. I am stuck in problem 474 A where I am getting runtime error. But I can't any fault in it. I use C. Here is my code:
#include<stdio.h>
int main()
{
int a, i, j, b, arr[102];
char ch, str2[101], c;
char str1[30] = "qwertyuiopasdfghjkl;zxcvbnm,./";
for (i = 0; i<30; i++)
arr[(str1[i])] = i;
scanf("%c%s", &ch, str2);
if (ch == 'R')
{
for (i = 0; str2[i]; i++)
{
printf("%c", str1[(arr[str2[i]] - 1)]);
}
printf("\n");
}
else {
for (i = 0; str2[i]; i++)
{
printf("%c", str1[(arr[str2[i]] + 1)]);
}
printf("\n");
}
return 0;
}
Can you find what is wrong in it?
Please try this, if I understood the problem correctly this works.
// MOLE is typing to the right or to the left of 3 rows of keys
// qwertyuiop
// asdfghjkl;
// zxcvbnm,./
// encoded as: !qwertyuiop!asdfghjkl;!zxcvbnm,./!
// where '!' detects input errors
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main( void )
{
int i;
char ch;
char str2[101];
char kstr1[50];
char *poschar; // pointer to char
int int_poschar = 0;
int translated_position = 0;
int right = 0;
int left = 0;
strcpy( kstr1, "!qwertyuiop!asdfghjkl;!zxcvbnm,./!" );
printf( "\n Please enter R or L and press enter\n" );
scanf( " %c ", &ch );
ch = toupper( ch );
if ( ch == 'R' || ch == 'L' ) ; // good input say nothing
else
{
printf( "\nPlease try again with L or R ( or l or r ) " );
exit( 0 );
}
printf( "\n Please enter a word and press enter\n" );
scanf( " %100s", str2 );
strcpy( str2, strlwr( str2 ) );
if ( ch == 'R' )
{
printf( "\nRIGHT translate:\n%s\n", str2 );
right = 1;
}
else if ( ch == 'L' )
{
printf( "\nLEFT translate:\n%s\n", str2 );
left = 1;
}
getchar( );
for ( i = 0; str2[i]; i++ )
{
poschar = strchr( kstr1, str2[i] );
if ( poschar != NULL )
{
int_poschar = poschar - kstr1; // find prev pos in array
if ( right )
translated_position = int_poschar - 1;
else if ( left )
translated_position = int_poschar + 1;
else
{
printf( "\n you've got a bug !" );
exit( 0 );
}
if ( kstr1[translated_position] == '!' )
{
if ( right )
printf( "\n not possible, MOLE wrote 1 key to the right" );
else
printf( "\n not possible, MOLE wrote 1 key to the left" );
getchar( );
exit( 0 );
}
printf( "%c", kstr1[int_poschar - 1] );
} // endif ( poschar != NULL )
}
exit( 0 );
}

C Program passing file-io to function

This program is supposed to shift a sentence by a certain amount.
If i have a shift of 3 then the letter a should be d. However when I pass the string into my shift function it doesn't shift any of my values.
#include <stdio.h>
#define MAX_LEN 100
void decode(char *sentence, int shift);
int main(void)
{
FILE *ifp;
FILE *ofp;
char str[MAX_LEN];
int shift_by = 0;
scanf("%d", &shift_by);
ifp = fopen("input.txt", "r");
ofp = fopen("output.txt", "w");
if (ifp == NULL) {
printf("FILE doesnt open");
return 1;
}
while(fgets(str, MAX_LEN, ifp) != NULL) {
shift(str, shift_by);
fprintf(ofp," %s", str);
}
fclose(ifp);
fclose(ofp);
return 0;
}
void decode(char *sentence, int shift)
{
char *p;
p = sentence;
if ((*p >= 'a') && (*p <= 'z')) {
*p = (*p - 'a') + shift % 26 + 'a';
}
if ((*p >= 'A') && (*p <= 'Z')) {
*p = (*p - 'A' + shift) % 26 + 'A';
}
}
Please try the code below it works. You thought 'decode' but you typed 'shift'. I simplified the code a bit. Now you can experiment to make it work with pointers.
Have fun.
#include <stdio.h>
#define MAX_LEN 100
void decode( char *sentence, int shift );
int main( void )
{
FILE *ifp;
FILE *ofp;
char str[MAX_LEN];
int shift_by = 0;
printf( "\nPlease enter shift by and press enter\n" );
scanf( " %d", &shift_by );
ifp = fopen( "input.txt", "r" );
ofp = fopen( "output.txt", "w" );
if ( ifp == NULL )
{
printf( "FILE doesnt open" );
return 1;
}
while ( fgets( str, MAX_LEN, ifp ) != NULL )
{
decode( str, shift_by );
fprintf( ofp, " %s", str );
}
fclose( ifp );
fclose( ofp );
return 0;
}
void decode( char *sentence, int shift )
{
int i = 0;
char p;
while ( p = sentence[i] )
{
if ( ( p >= 'a' ) && ( p <= 'z' ) )
{
p = ( p - 'a' ) + shift % 26 + 'a';
}
if ( ( p >= 'A' ) && ( p <= 'Z' ) )
{
p = ( p - 'A' + shift ) % 26 + 'A';
}
sentence[i] = p;
i++;
}
}

C source code to change first letters of words from lowercase to uppercase in a string

I have a C source code, but I have a problem with it. I want to convert the first letters of words in a string that I enter from lowercase to uppercase, but it changes all letters to uppercase. Can you help me solve this?
#include <stdio.h>
#include <ctype.h>
#include <conio.h>
void main()
{
char sentence[100];
int count, ch, i;
int str[32];
printf("Enter a sentence \n");
for (i = 0; (sentence[i] = getchar()) != '\n'; i++)
{
;
}
sentence[i] = '\0';
/* shows the number of chars accepted in a sentence */
count = i;
printf("The given sentence is : %s", sentence);
printf("\n Case changed sentence is: ");
for (i = 0; i < count; i++)
{
ch = islower(sentence[i])? toupper(sentence[i]) : tolower(sentence[i]);
putchar(ch);
}
getch();
}
e.g.
Input: welcome to Sharif university
Desired output: Welcome To Sharif University
Actual output: WELCOME TO SHARIF UNIVERSITY
You must have check if the current char is a space and then only use toupper on the character after the space.
ch = ' ';
for (i = 0; i < count; i++)
{
ch = isspace(ch) ? toupper(sentence[i]) : tolower(sentence[i]);
putchar(ch);
}
Try the following code.:)
#include <stdio.h>
#include <ctype.h>
#define N 100
int main( void )
{
char sentence[N];
char *p = sentence;
printf( "Enter a sentence: " );
if ( !fgets( sentence, sizeof( sentence ), stdin ) ) sentence[0] = '\0';
printf( "\nThe given sentence is : %s", sentence );
do
{
while ( isblank( ( unsigned char )*p ) ) ++p;
if ( islower( ( unsigned char )*p ) ) *p = toupper( *p );
while ( *p && !isblank( ( unsigned char )*p ) ) ++p;
} while ( *p );
printf( "\nCase changed sentence is: %s", sentence );
return 0;
}
The output is
The given sentence is : welcome to Sharif university
Case changed sentence is: Welcome To Sharif University
If yor compiler does not support function isblank then you can substitute it for isspace
It seems that a more correct approach will be to use only isalpha because in general case after a blank there can be for example a digit or punctuation
#include <stdio.h>
#include <ctype.h>
#define N 100
int main( void )
{
char sentence[N];
char *p = sentence;
printf( "Enter a sentence: " );
if ( !fgets( sentence, sizeof( sentence ), stdin ) ) sentence[0] = '\0';
printf( "\nThe given sentence is : %s", sentence );
do
{
while ( *p && !isalpha( ( unsigned char )*p ) ) ++p;
if ( islower( ( unsigned char )*p ) ) *p = toupper( *p );
while ( isalpha( ( unsigned char )*p ) ) ++p;
} while ( *p );
printf( "\nCase changed sentence is: %s", sentence );
return 0;
}
If you do not want to change the original string then the code will look like
#include <stdio.h>
#include <ctype.h>
#define N 100
int main( void )
{
char sentence[N];
char *p = sentence;
printf( "Enter a sentence: " );
if ( !fgets( sentence, sizeof( sentence ), stdin ) ) sentence[0] = '\0';
printf( "\nThe given sentence is : %s", sentence );
printf( "\nCase changed sentence is: " );
do
{
while ( *p && !isalpha( ( unsigned char )*p ) ) putchar( *p++ );
if ( islower( ( unsigned char )*p ) ) putchar( toupper( *p++ ) );
while ( isalpha( ( unsigned char )*p ) ) putchar( *p++ );
} while ( *p );
return 0;
}
You need to check for characters which have a space preceding them and upper case them. You also need to check for the first character which is a special case as it does not have a space preceding it.
#include <string.h>
#include <stdio.h>
int main (void)
{
char str[] = "this is a test string";
int loop;
for (loop=-1; loop<(int) strlen(str)-1; loop++)
{
// Possible upper case required?
if (loop < 0 || str[loop]==' ')
if (str[loop+1] >= 'a' && str[loop+1] <='z')
str[loop+1] = (str[loop+1] - 'a') + 'A';
}
printf ("string is : %s\n", str);
return 0;
}
Output:
string is : This Is A Test String

Resources