#include <stdio.h>
#define FINISH 'Z'
int main(void){
int spacenm, currentspacenm, i;
char ini, inirecord;
int rownm, currentrownm;
printf("PLease enter a random uppercase letter: ");
scanf("%c", &inirecord);
spacenm = rownm = FINISH - inirecord;
for (i = 0; i<= spacenm; i++)
printf(" ");
printf("%c\n", inirecord);
i = 0;
for (currentrownm = 1; currentrownm <= rownm; currentrownm ++){
for (currentspacenm = 1; currentspacenm <= spacenm; currentspacenm++)
printf(" ");
spacenm--;
for (ini = inirecord; ini<=inirecord+i; ini++)
printf("%c", ini);
i++;
for (; ini>=inirecord; ini--)
printf("%c", ini);
printf("\n");
}
return 0;
}
I wonder if there're better ways where less variables are needed or less redundant code structure is used to improve efficiency.
We beginners should help each other.:)
There is no check in your program relative to whether the user input is valid.
Also if I'm not mistaken not all coding tables as for example the EBCDIC table contain sequentially upper letters.
There is no need to write a separate snippet of code to output the first row of the pyramid as you are doing
for (i = 0; i<= spacenm; i++)
printf(" ");
printf("%c\n", inirecord);
Using formating you can eliminate the number of loops.
Take into account that in general instead of this format specification
scanf("%c", &inirecord);
^^^^
you should use the following
scanf(" %c", &inirecord);
^^^^^
Otherwise control characters will be also read.
Here are my three cents.:)
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void)
{
const char *letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const size_t N = strlen( letters );
while ( 1 )
{
char alpha[3];
_Bool exit_status;
const char *p;
do
{
printf( "PLease enter a random uppercase letter (Enter - exit ): " );
exit_status = fgets( alpha, sizeof( alpha ), stdin ) == NULL || alpha[0] == '\n';
if ( !exit_status )
{
p = NULL;
if ( alpha[1] == '\n' )
{
alpha[0] = toupper( ( unsigned char )alpha[0] );
p = strchr( letters, alpha[0] );
}
}
} while ( !exit_status && !p );
if ( exit_status ) break;
int n = &letters[N] - p;
putchar( '\n' );
for ( int i = 0; i < n; i++ )
{
printf( "%*c", n - i, alpha[0] );
int j = 0;
while ( j != i ) putchar( p[++j] );
while ( j != 0 ) putchar( p[--j] );
putchar( '\n' );
}
putchar( '\n' );
}
return 0;
}
The program output might look like
PLease enter a random uppercase letter (Enter - exit ): Z
Z
PLease enter a random uppercase letter (Enter - exit ): Y
Y
YZY
PLease enter a random uppercase letter (Enter - exit ): X
X
XYX
XYZYX
PLease enter a random uppercase letter (Enter - exit ): A
A
ABA
ABCBA
ABCDCBA
ABCDEDCBA
ABCDEFEDCBA
ABCDEFGFEDCBA
ABCDEFGHGFEDCBA
ABCDEFGHIHGFEDCBA
ABCDEFGHIJIHGFEDCBA
ABCDEFGHIJKJIHGFEDCBA
ABCDEFGHIJKLKJIHGFEDCBA
ABCDEFGHIJKLMLKJIHGFEDCBA
ABCDEFGHIJKLMNMLKJIHGFEDCBA
ABCDEFGHIJKLMNONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXYXWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXYZYXWVUTSRQPONMLKJIHGFEDCBA
PLease enter a random uppercase letter (Enter - exit ):
Related
I am having an issue with the output of my code, which is trying to return an array backwards in c using pointers. Do you guys have any solutions to the error I am getting?
Sample input:
Please enter the array size: 3
Please enter 3 elements:
4, 5, 7
Segmentation fault (core dumped)
Code:
#include <stdio.h>
int main(void){
int size, i;
int *pointer;
int arr[size];
printf("Please enter the array size: ");
scanf("%d/n", &size);
pointer = &arr[0];
printf("Please enter %d elements: \n", size);
for(i = 0; i < size; i++){
scanf("%d", arr[i]);
pointer++;
}
pointer = &arr[size - 1];
printf("The reversed array is \n");
for(i = size; i > 0; i--){
printf("%d", arr[i]);
pointer--;
}
return 0;
}
The task is not simple for beginners like you and me.
As I have understood the user can enter any number of integers in one line and all entered integers in the line must be outputted like
You entered 2
In this case neither array nor character array nor integer array will help. And in fact you need not to define an array if you want only to output numbers stored in the input buffer.
In this case you can just use the standard function getchar. Using the function in a loop you can read all numbers placed by the user in one line in the I/O buffer.
Here is a sample program. It is a little complicated because I allow the user to enter sign symbols.
There is no check in the program whether the user entered not a digit or a sign. You can develop the program further. The program demonstrates an approach to solve the task.
#include <stdio.h>
#include <ctype.h>
int main( void )
{
const int Base = 10;
printf( "Enter a seria of integer numbers in one line: " );
int c;
int sign = 0;
int num = 0;
do
{
c = getchar();
if (c == EOF || c == '\n' )
{
if (sign)
{
printf( "You entered %d\n", num );
}
}
else if (isblank( ( unsigned char )c ))
{
if (sign)
{
printf( "You entered %d\n", num );
sign = 0;
num = 0;
}
}
else
{
if (c == '-' || c == '+')
{
if (sign)
{
printf( "You entered %d\n", num );
num = 0;
}
sign = c == '-' ? -1 : 1;
}
else if (isdigit( ( unsigned char )c ))
{
c -= '0';
if (sign == 0) sign = 1;
if (sign == 1)
{
num = Base * num + c;
}
else
{
num = Base * num - c;
}
}
}
} while (c != EOF && c != '\n');
}
The program output might look for example like
Enter a seria of integer numbers in one line: 1 -1 +12-12+13 +14 -15
You entered 1
You entered -1
You entered 12
You entered -12
You entered 13
You entered 14
You entered -15
If you want to enter several lines of numbers and output numbers that are present in each line then the program can look the following way
#include <stdio.h>
#include <ctype.h>
int main( void )
{
const int Base = 10;
size_t i = 0;
while (1)
{
printf( "Enter a seria of integer numbers in one line (or press just Enter to exit): " );
int c = getchar();
if (c == EOF || c == '\n') break;
ungetc( c, stdin );
printf( "Line %zu contains the following numbers:\n", i++ );
int sign = 0;
int num = 0;
do
{
c = getchar();
if (c == EOF || c == '\n')
{
if (sign)
{
printf( "You entered %d\n", num );
}
}
else if (isblank( ( unsigned char )c ))
{
if (sign)
{
printf( "You entered %d\n", num );
sign = 0;
num = 0;
}
}
else
{
if (c == '-' || c == '+')
{
if (sign)
{
printf( "You entered %d\n", num );
num = 0;
}
sign = c == '-' ? -1 : 1;
}
else if (isdigit( ( unsigned char )c ))
{
c -= '0';
if (sign == 0) sign = 1;
if (sign == 1)
{
num = Base * num + c;
}
else
{
num = Base * num - c;
}
}
}
} while (c != EOF && c != '\n');
putchar( '\n' );
}
}
The program output might look for example like
Enter a seria of integer numbers in one line (or press just Enter to exit): 1 -2 3 +4
Line 0 contains the following numbers:
You entered 1
You entered -2
You entered 3
You entered 4
Enter a seria of integer numbers in one line (or press just Enter to exit): 11-12 13+14
Line 1 contains the following numbers:
You entered 11
You entered -12
You entered 13
You entered 14
Enter a seria of integer numbers in one line (or press just Enter to exit):
As the program just outputs entered numbers then actually there is no need to build an object of the type int like
num = Base * num + c;
You could just output adjacent digits in a line.
int array[100];
int n;
scanf("%d", &n);
for(int i=0; i<n; i++) {
scanf("%d", &array[i]);
}
for(int i=0; i<n; i++) {
printf("You entered %d \n", array[i]);
}
We use the array to get all of the values, and just print them out at the end.
In C and C++ it does not matter if the values are separated by space or a newline, so you can get every integer in a single line if separated by spaces.
output
3
1 2 3
You entered 1
You entered 2
You entered 3
C makes this very easy, but you need to leverage some library functions. At the most simple:
use fgets() and strpbrk() to obtain and verify a line of text
use strtok() and strtol() to parse and verify integer values.
What you do with those values is up to you. Following your example prompt, let’s just print them.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int error( const char * message, const char * value )
{
fprintf( stderr, "%s%s\n", message, value );
return 1;
}
int main()
{
printf( "Input: " );
// Get all input on a single line
char text[1000];
fgets( text, sizeof(text), stdin );
// Verify that the entire line of input was obtained
char * nl = strpbrk( text, "\r\n" );
if (!nl) return error( "Line too long!", "" );
*nl = '\0';
puts( "Output:" );
// For each whitespace-delimited (spaces, tabs) token in the line:
for (char * token = strtok( text, " \t" ); token; token = strtok( NULL, " \t" ))
{
// Attempt to convert it to an integer
char * nok;
int n = strtol( token, &nok, 10 );
if (*nok) return error( "Invalid integer value: ", token );
// Success!
printf( "You entered %d\n", n );
}
return 0;
}
Notice also how it is OK to create a little helper function (error()). You can make helpers as complex or simple as you need. For this helper, all we need was to complain with one or two strings and return an “error happened” exit code that main() can pass right to the shell.
fgets can be used to read a line.
strtol can parse integers and report overflow and invalid input.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
int parselint ( char *line, int *value, char **end) {
long int number = 0;
errno = 0;
number = strtol ( line, end, 10);
if ( *end == line) {// nothing was parsed. no digits
size_t span = strcspn ( *end, "-+0123456789"); // characters to next int
if ( ! span) {
span = 1;
}
fprintf ( stderr, "problem parsing: %.*s\n", (int)span, line);
*end += span; // advance pointer to next int
return 0;// return failure
}
if ( ( errno == ERANGE && ( number == LONG_MAX || number == LONG_MIN))
|| ( errno != 0 && number == 0)) {// parsing error from strtol
fprintf ( stderr, "problem %.*s", (int)(*end - line), line);
perror ( " ");
return 0;
}
if ( number > INT_MAX || number < INT_MIN) {
fprintf ( stderr, "problem %.*s ", (int)(*end - line), line);
fprintf ( stderr, "out of int range\n");
return 0;
}
*value = number;//assign number to pointer
return 1;//success
}
int main ( void) {
char line[4096] = "";
char *parse = line;
int number = 0;
fgets ( line, sizeof line, stdin);
line[strcspn ( line, "\r\n")] = 0; // remove newline
while ( *parse) {
if ( 1 == parselint ( parse, &number, &parse)) {
printf ( "you entered %d\n", number);
}
}
return 0;
}
So I am trying to make a tic-tac-toe game in C and I've gotten most of the code written out, no error messages, but I want to know what code to add to get the computer to play the game as well. I just don't know what else to add here to make sure the game is interact-able and not just the user typing in one letter and being done. If anyone could help, that'd be appreciated! The code is below:
#include <time.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
system("clear");
const char ROWS = 3;
const char COLS = 3;
int rows, cols, tile = 1, choice;
for (rows = 0; rows < ROWS; rows++)
{
for (cols = 0; cols < COLS; cols++)
{
printf("[%d]", tile++);
}
printf("\n");
}
printf("\nWhere would you like to put your X: ");
scanf("%d", &choice);
tile = 1;
for (rows = 0; rows < ROWS; rows++)
{
for (cols = 0; cols < COLS; cols++)
{
if (tile == 1 || tile == 2 || tile == 3 || tile == 4 || tile == 5 || tile == 6 || tile== 7 || tile == 8 || tile == 9)
{
printf("[%d]", tile++);
}
if (choice == tile)
{
tile -= tile;
printf("[X]");
choice += 1000;
}
}
printf("\n");
}
return 0;
}
Instead of worrying about implementing a computer player, I think your first step shoud be to offer support for a second human player.
First, you will need some array to represent the state of the game board. A multi-dimensional array of type char seems appropriate, in which each char can have one of three values:
'E' for empty
'X' for first player
'O' for second player
You could define the array like this:
char board[3][3];
Also, you will need an additional variable to keep track of whose turn it currently is. A variable of type bool with the name first_players_turn would probably be appropriate. When it is the first player's turn, this variable should be set to true, otherwise to false.
I also suggest that you create your own function print_board for printing the game board to the screen.
You will also need a function evaluate_game_state in order to determine the state of the game, which can be one of the following:
The game is still undecided.
The game is a draw.
Player 1 has won.
Player 2 has won.
To represent these 4 possible game states, I recommend that you use an enum, like this:
enum game_state
{
GAMESTATE_UNDECIDED,
GAMESTATE_DRAW,
GAMESTATE_WINNER_PLAYER1,
GAMESTATE_WINNER_PLAYER2
};
You can now declare the function evaluate_game_state like this:
enum game_state evaluate_game_state( char board[3][3] );
As long as the function evaluate_game_state returns GAMESTATE_UNDECIDED, you will have to prompt the user for input in a loop.
Here is my implementation of everything stated above, which I have tested a bit and seems to work, but I have not tested all corner cases. I took over the function get_int_from_user from this answer of mine from another question, and made a slight modification, so that it accepts variadic arguments, so that I can pass a string containing %d to that function and it treats it as a printf format specifier. Although your implementation of using printf and scanf would also work, that solution has the disadvantage that scanf does not perform proper input validation, so I used my function get_int_from_user instead.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include <errno.h>
#include <stdarg.h>
#include <stdbool.h>
enum game_state
{
GAMESTATE_UNDECIDED,
GAMESTATE_DRAW,
GAMESTATE_WINNER_PLAYER1,
GAMESTATE_WINNER_PLAYER2
};
void init_board( char board[3][3] );
void print_board( char board[3][3] );
enum game_state evaluate_game_state( char board[3][3] );
int get_int_from_user( const char *prompt, ... );
int main( void )
{
char board[3][3];
bool first_players_turn = true;
enum game_state gs;
init_board( board );
while ( ( gs = evaluate_game_state( board ) ) == GAMESTATE_UNDECIDED )
{
//prompt user for input until input is valid
for (;;)
{
int input;
print_board( board );
input = get_int_from_user(
"It is player %d's turn.\n"
"Please select a move (1-9): ",
first_players_turn ? 1 : 2
);
if ( 1 <= input && input <= 9 )
{
int x = ( input - 1 ) % 3;
int y = ( input - 1 ) / 3;
//make sure field is empty
if ( board[y][x] != 'E' )
{
printf( "That field is already occupied!\n\n" );
continue;
}
//perform the move
board[y][x] = first_players_turn ? 'X' : 'O';
first_players_turn = !first_players_turn;
break;
}
printf( "Input must be between 1 and 9!\n\n" );
}
}
//game is over
print_board( board );
switch ( gs )
{
case GAMESTATE_DRAW:
printf( "The game is a draw.\n\n" );
break;
case GAMESTATE_WINNER_PLAYER1:
printf( "Player 1 wins!\n\n" );
break;
case GAMESTATE_WINNER_PLAYER2:
printf( "Player 2 wins!\n\n" );
break;
}
}
void init_board( char board[3][3] )
{
for ( int i = 0; i < 3; i++ )
for ( int j = 0; j < 3; j++ )
board[i][j] = 'E';
}
void print_board( char board[3][3] )
{
printf( "\n\n" );
for ( int i = 0; i < 3; i++ )
{
for ( int j = 0; j < 3; j++ )
{
//add spacing if necessary
if ( j != 0 )
printf( " " );
if ( board[i][j] == 'E' )
//replace empty field with number of field
printf( "%d", (i*3) + (j+1) );
else
printf( "%c", board[i][j] );
}
//end the line
printf( "\n" );
}
printf( "\n" );
}
enum game_state evaluate_game_state( char board[3][3] )
{
//check for horizontal wins
for ( int i = 0; i < 3; i++ )
{
char possible_winner = board[i][0];
if ( possible_winner != 'E' )
{
if ( possible_winner == board[i][1] && possible_winner == board[i][2] )
{
return possible_winner == 'X' ? GAMESTATE_WINNER_PLAYER1 : GAMESTATE_WINNER_PLAYER2;
}
}
}
//check for vertical wins
for ( int i = 0; i < 3; i++ )
{
char possible_winner = board[0][i];
if ( possible_winner != 'E' )
{
if ( possible_winner == board[1][i] && possible_winner == board[2][i] )
{
return possible_winner == 'X' ? GAMESTATE_WINNER_PLAYER1 : GAMESTATE_WINNER_PLAYER2;
}
}
}
//check for diagonal-down win
{
char possible_winner = board[0][0];
if ( possible_winner != 'E' )
{
if ( possible_winner == board[1][1] && possible_winner == board[2][2] )
{
return possible_winner == 'X' ? GAMESTATE_WINNER_PLAYER1 : GAMESTATE_WINNER_PLAYER2;
}
}
}
//check for diagonal-up win
{
char possible_winner = board[2][0];
if ( possible_winner != 'E' )
{
if ( possible_winner == board[1][1] && possible_winner == board[0][2] )
{
return possible_winner == 'X' ? GAMESTATE_WINNER_PLAYER1 : GAMESTATE_WINNER_PLAYER2;
}
}
}
//check if board is full
for ( int i = 0; i < 3; i++ )
for ( int j = 0; j < 3; j++ )
if ( board[i][j] == 'E' )
return GAMESTATE_UNDECIDED;
return GAMESTATE_DRAW;
}
int get_int_from_user( const char *prompt, ... )
{
for (;;) //loop forever until user enters a valid number
{
va_list args;
char buffer[1024], *p;
long l;
//prompt user for input
va_start( args, prompt );
vprintf( prompt, args );
va_end( args );
//get one line of input from input stream
if ( fgets( buffer, sizeof buffer, stdin ) == NULL )
{
fprintf( stderr, "unrecoverable error reading from input\n" );
exit( EXIT_FAILURE );
}
//make sure that entire line was read in (i.e. that
//the buffer was not too small)
if ( strchr( buffer, '\n' ) == NULL && !feof( stdin ) )
{
int c;
printf( "line input was too long!\n" );
//discard remainder of line
do
{
c = getchar();
if ( c == EOF )
{
fprintf( stderr, "unrecoverable error reading from input\n" );
exit( EXIT_FAILURE );
}
} while ( c != '\n' );
continue;
}
//attempt to convert string to number
errno = 0;
l = strtol( buffer, &p, 10 );
if ( p == buffer )
{
printf( "error converting string to number\n" );
continue;
}
//make sure that number is representable as an "int"
if ( errno == ERANGE || l < INT_MIN || l > INT_MAX )
{
printf( "number out of range error\n" );
continue;
}
//make sure that remainder of line contains only whitespace,
//so that input such as "6sdfh4q" gets rejected
for ( ; *p != '\0'; p++ )
{
if ( !isspace( (unsigned char)*p ) )
{
printf( "unexpected input encountered!\n" );
//cannot use `continue` here, because that would go to
//the next iteration of the innermost loop, but we
//want to go to the next iteration of the outer loop
goto continue_outer_loop;
}
}
return l;
continue_outer_loop:
continue;
}
}
This program has the following behavior:
1 2 3
4 5 6
7 8 9
It is player 1's turn.
Please select a move (1-9): 5
1 2 3
4 X 6
7 8 9
It is player 2's turn.
Please select a move (1-9): 4
1 2 3
O X 6
7 8 9
It is player 1's turn.
Please select a move (1-9): 1
X 2 3
O X 6
7 8 9
It is player 2's turn.
Please select a move (1-9): 6
X 2 3
O X O
7 8 9
It is player 1's turn.
Please select a move (1-9): 9
X 2 3
O X O
7 8 X
Player 1 wins!
If you want to make a good computer opponent, then I suggest that you take a look at the Wikipedia article on Minimax.
There is a question: I should scan a number with 300 digits and print the sum the digits but I cant scan it with long long int and I dont know what to do.
You can scan the number as a string with fgets() or simply read one byte at a time with getchar():
#include <stdio.h>
int main() {
int c;
int sum = 0;
while ((c = getchar()) != EOF) {
if (c >= '0' && c <= '9')
sum += c - '0';
else
break;
}
printf("sum: %d\n", sum);
return 0;
}
I you must use scanf(), here is an alternative:
#include <stdio.h>
int main() {
char buf[2];
int sum = 0;
while (scanf("%1[0-9]", buf) == 1) {
sum += *buf - '0';
}
printf("sum: %d\n", sum);
return 0;
}
#include <stdio.h>
int main()
{
char digit;
int sum = 0;
while ( scanf("%c", &digit) != EOF)
{
sum += digit - '0';
}
printf("sum: %d\n", sum);
return 0;
}
The most straight forward solution seems to be to repeatedly read in 1-digit ints and sum them up while that works.
One digit numbers can easily be read into an int (no long needed) and even the sum of 300 digits will not exceed an int.
#include <stdio.h>
int main()
{
int digit=0;
int sum=0;
while(1==scanf("%1d",&digit))sum+=digit;
printf("sum:%d\n", sum);
return 0;
}
This admittedly (thanks chqrlie for pointing out) expect an end of line, as it comes with e.g. test input at online compilers or judges. In an interactive prompt
... a single line of digit will not suffice, an explicit end of file with ^D is needed.
In such a case you need to enter a number as a string.
To enter a number you should use the standard function fgets. The corresponding character array must have 302 characters: 300 characters for digits, one character for the new line character '\n' that is appended by the function fgets to the entered string and one character for the terminating zero character '\0' of the string.
If the new line character '\n' is not present in the string it means that the user entered more than 300 characters.
Also the user can enter a number with leading or trailing spaces.
You need to check that the entered string contains a valid number.
Here is a demonstration program.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int is_valid_number( const char *number )
{
while ( isblank( ( unsigned char )*number ) ) ++number;
int valid = *number != '\0';
if ( valid )
{
while ( isdigit( ( unsigned char )*number ) ) ++number;
while ( isblank( ( unsigned char )*number ) ) ++number;
valid = *number == '\0';
}
return valid;
}
int main( void )
{
enum { N = 300 };
char number[N + 2] = { 0 };
printf( "Enter a non-negative number (no greater than %d digits): ", N );
fgets( number, sizeof( number ), stdin );
int valid = strchr( number, '\n' ) != NULL;
char *p = number;
if ( valid )
{
number[ strcspn( number, "\n" ) ] = '\0';
while ( isblank( ( unsigned char )*p ) ) ++p;
valid = is_valid_number( p );
}
if ( !valid )
{
puts( "Invalid number." );
}
else
{
unsigned int sum = 0;
for ( char *digit = p; isdigit( ( unsigned char )*digit ); ++digit )
{
sum += *digit - '0';
}
printf( "The sum of digits = %u\n", sum );
}
}
Its output might look like
Enter a non-negative number (no greater than 300 digits): 1234567890123456789012345678901234567890
The sum of digits = 180
you can use char to scan each digit. also in this way you do not need string.enter image description here
I want to have a loop of scanf that repeats until the user presses enter.
#include <stdio.h>
int main() {
char num[127];
int i=-1;
do
{
i++;
scanf("%c ", &num[i]);
}while ((num[i]!='\n') && i<=127);
printf("%c", num[3]);
return 0;
}
With this code, when I input > 0 1 2 3 4 5 6 , the output num[3] is nothing. How can I fix this? I already tried using while and for, but i get the same problem.
What you need is something like the following
#include <stdio.h>
#include <ctype.h>
int main(void)
{
enum { N = 127 };
char num[N];
size_t len = 0;
char c;
while ( len < N && scanf( "%c", &c ) == 1 && c != '\n' )
{
if ( !isblank( ( unsigned char )c ) ) num[len++] = c;
}
if ( 3 < len ) printf( "%c\n", num[3] );
return 0;
}
The if statement
if ( !isblank( ( unsigned char )c ) ) num[len++] = c;
may be substituted for this one if you are going to enter only digits
if ( isdigit( ( unsigned char )c ) ) num[len++] = c;
If to use getchar then the program will look like
#include <stdio.h>
#include <ctype.h>
int main(void)
{
enum { N = 127 };
char num[N];
size_t len = 0;
int c;
while ( len < N && ( c = getchar() ) != EOF && c != '\n' )
{
if ( isdigit( c ) ) num[len++] = c;
}
if ( 3 < len ) printf( "%c\n", num[3] );
return 0;
}
Using the format specifier "%c ", scanf will never write \n into buf[i] except for i == 0. (If the first character of input is a newline, it will be written to buf[0]. Otherwise, all newlines will be discarded because of the whitespace in the conversion specifier.) If you are entering data interactively, the program will not terminate correctly, since eventually the scanf will invoke undefined behavior when it tries to write to buf[127]
Also, you're not checking the value returned by scanf. It's not clear to me what you want to do with whitespace, but perhaps you want something like:
#include <stdio.h>
int
main(void)
{
char num[127];
int i=-1;
while( i < 125 && scanf("%c", &num[++i]) == 1 && num[i] != '\n' ){
; /* scanf is the wrong tool for this!! */
}
printf("%c", num[3]);
return 0;
}
(But note that using scanf is absolutely the wrong way to read a single character. fgetc, getc, and getchar are better for that.)
Please help me in understanding the below code.
The function get_digit takes a character argument by address. I am unable to get what
scanf("%1[0123456789]", ch) does here.
If I give 1234 on the terminal then it takes only the first digit. Same is if I give 2345 it takes 2. I have never came across such usage of scanf. Please help me in understanding this feature.
int get_digit ( char *ch )
{
int rc;
printf ( "Enter a single digit: " );
fflush ( stdout );
if ( rc = scanf ( "%1[0123456789]", ch ) == 1 ) {
jsw_flush();
}
return rc;
}
void jsw_flush ( void )
{
int ch;
do
ch = getchar();
while ( ch != '\n' && ch != EOF );
clearerr ( stdin );
}
void fill_table ( char table[] )
{
char ch;
while ( get_digit ( &ch ) ) {
unsigned i = ch - '0';
if ( table[i] != 0 ) {
printf ( "That index has been filled\n" );
}
else {
table[i] = ch;
}
}
}
void show_table ( const char table[], size_t size )
{
size_t i;
for ( i = 0; i < size; i++ ) {
printf ( "%c\n", table[i] != 0 ? table[i] : '~' );
}
}
scanf ( "%1[0123456789]", ch ) scans 1 character (%1) which is a decimal digit ([0123456789]) int the characer pointed to by ch.
The number immediately following the % is the field width, how many characters (maximally) to scan. The characters inside the square brackets are the characters scanf will accept. The scan ends when a character not listed is encountered.
An extremely simple example to scan two-digit numbers:
#include <stdlib.h>
#include <stdio.h>
int main(void) {
char chs[2] = {0}; // space for two digits, zero-initialized
unsigned u = 0, i;
if (scanf("%2[0123456789]",&chs[0]) == 1) {
// parse the number
for(i = 0; i < 2 && chs[i]; ++i) {
u = 10*u + chs[i] - '0';
}
printf("Got %u\n",u);
} else {
puts("Scan failed.");
}
return EXIT_SUCCESS;
}
Of course, instead of parsing ourselves, we could make the character array one longer than we expect digits (zero-initialise!, scanf doesn't add a 0-terminator with that format) and leave the parsing to strtoul(chs,NULL,10).