This question already has answers here:
Difference between scanf("%c", &c) and scanf(" %c", &c) [duplicate]
(3 answers)
Reading a character with scanf_s
(3 answers)
Closed 4 years ago.
In the main function if i simply declare the replacement character like this..
c = '*';
the program will keep looping normal and work normal after user enters y or Y to proceed.
But if i want the user to enter the replacement character and do this..
c = getchar();
after the user enters either y or Y, the loop ends and the program just closes.
Why is this?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define BUFF_SIZE 512
void getRandomStr(char s1[]);
void strreplace(char s1[], char chrs[], char c);
void check(char s2[], char chrs[]);
char cont(void);
int main()
{
char s1[BUFF_SIZE];
char s2[BUFF_SIZE], c;
char proceed = 0;
do {
getRandomStr(s1);
printf("Your random string is: %s\n", s1);
/* gets(s1) */
printf("\nPlease enter up to 20 letters to be replaced: ");
gets(s2);
printf("\nPlease enter a replacement character (Ex. *, $, etc.): ");
c = getchar();
check(s1, s2);
printf("\nModified string after replacement is: ");
strreplace(s1, s2, c);
proceed = cont();
} while (proceed == 'Y' || proceed == 'y');
}
void getRandomStr(char s1[]) {
int i;
srand(time(NULL));
for (i = 0; i < 41; i++) {
char c = rand() % 26 + 'A';
s1[i] = c;
}
s1[41] = '\0';
}
void strreplace(char s1[], char chrs[], char c)
{
int i = 0;
while (chrs[i] != '\0') {
for (int j = 0; s1[j] != '\0'; j++) {
if (s1[j] == chrs[i])
{
s1[j] = c;
}
}
i++;
}
puts(s1);
}
char cont()
{
char proceed;
printf("\nWould you like to run the program again (y/n)? ");
scanf_s("%c%*c", &proceed);
return proceed;
}
void check(char s2[], char chrs[])
{
int i = 0;
while (chrs[i] != '\0') {
for (int j = 0; s2[j] != '\0'; j++) {
if (!(chrs[i] >= 'A' && chrs[i] <= 'Z'))
{
printf("An invalid character was entered.\n");
break;
}
}
i++;
}
}
Related
After i put a name in the terminal and it is shorter, then 20 chars, it wants inputs until i have filled all the 20 positions in the array.
I know it is because of the for cycle i have there, but I don't know how else to fill that end of the array with nothing("").
In the array there is for example this "Helloworld\n123\n123"
Thank you for help in advance.
#define NAME 20
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
main(void) {
char name[NAME] = {""};
malloc(sizeof(name[NAME]));
printf("Choose your name: ");
for (int i = 0; i < NAME; i++) {
scanf("%c", &name[i]);
}
//Welcome and the name
printf("Welcome: ");
for (int i = 0; i < NAME; i++) {
printf("%c", name[i]);
}
return 0;
}
You need to stop reading at a newline (+should also check return codes).
A loop like:
size_t i=0;
for (; i < sizeof(name)-1; i++) {
if (1==(scanf("%c",&name[i]))){ if (name[i]=='\n') break; }
else if (feof(stdin)) break; //end of file?
else return perror("getchar"),1; //report error
}
name[i]='\0';
will achieve that (can also use getchar/getc/fgetc instead of scanf)
or you can use fgets:
if(NULL==fgets(name,sizeof(name),stdin)) return perror("fgets"),1;
//erase a possibly included newline at the end
//(won't be there if you pressed Ctrl+D twice rather than
//Enter to submit your input or if you're at the end of
//a stdin redirected from a file)
size_t len = strlen(name);
if(name[len-1]=='\n') name[len-1]='\0';
Whole program with both versions (in the if(0){...}else{...}) :
#define NAME 20
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main(void) {
char name[NAME] = {""};
//malloc(sizeof(name[NAME])); //a useless memory leak; don't do this!
printf("Choose your name: ");
if(0){
if(NULL==fgets(name,sizeof(name),stdin)) return perror("fgets"),1;
size_t len = strlen(name);
if(name[len-1]=='\n') name[len-1]='\0';
}else{
size_t i=0;
for (; i < sizeof(name)-1; i++) {
if (1==(scanf("%c",&name[i]))){ if (name[i]=='\n') break; }
else if (feof(stdin)) break; //end of file?
else return perror("getchar"),1;
}
name[i]='\0';
}
//Welcome and the name
printf("Welcome: ");
for (int i = 0; i < NAME; i++) {
printf("%c", name[i]);
}
return 0;
}
If you have to use scanf and %c format:
char *readLineUsingCharAndScanf(char *buff, size_t size, FILE *fi)
{
char ch;
char *wrk = buff;
while(size-- && fscanf(fi, "%c", &ch) == 1 && ch != '\n' ) *wrk++ = ch;
*wrk = 0;
return buff;
}
void dumpString(const char *restrict str, size_t size)
{
while(*str && size--)
{
printf("%03d [0x%02x] - %s\n", *str, *str, (*str >= 32 & *str <= 127) ? (char[]){'\'', *str, '\'', 0} : "not printable");
str++;
}
}
int main(void)
{
char name[20];
dumpString(readLineUsingCharAndScanf(name, 19, stdin), 20);
}
https://godbolt.org/z/vWvP68TbW
scanf() is not the best tool for your purpose. Here is a simple and safe solution:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define NAME 20
int main(void) {
char name[NAME];
int c;
size_t i;
printf("Enter your name: ");
i = 0;
while ((c = getchar()) != EOF && c != '\n') {
if (i < sizeof(name) - 1)
name[i++] = c;
}
name[i] = '\0';
//Welcome and the name
printf("Welcome: %s\n", name);
return 0;
}
If you must use scanf(), use this:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define NAME 20
int main(void) {
char name[NAME];
char c;
size_t i;
printf("Enter your name: ");
i = 0;
while (scanf("%c", &c) == 1 && c != '\n') {
if (i < sizeof(name) - 1)
name[i++] = c;
}
name[i] = '\0';
//Welcome and the name
printf("Welcome: %s\n", name);
return 0;
}
Thank you everyone for answering. Unfortunately the first two answers are too complicated for me yet. And the third one was not working properly.
But I found the simplest answer. :) Many thanks
#include <stdio.h>
int main(void)
{
char name[20];
printf("Choose your name: ");
scanf("%[^\n]*c",name);
printf("My name is %s",name);
}
For your needs I would use scanf with the string conversion specifier %s. In this case, the input name would be read and stored character by character in the buffer until the whitespace would be read. Here is the code.
#define NAME 20
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char name[NAME] = {""};
malloc(sizeof(name[NAME]));
printf("Choose your name: ");
scanf("%s", &name);
printf("%s", &name);
return 0;
}
I tried to write a function that inserts space at regular intervals in a string.
If a[50] is a string, and n is the preferred interval from the user,
insert_space(a,b,len,n) will insert blanks after the n'th column and will store the modified string in b.
#include <stdio.h>
int getinput(char temp[]);
void insert_space(char s1[],char s2[],int,int);
int main ()
{
int n, len;
char a[100], b[100];
printf("Enter the nth column number for inserting\n");
scanf("%d",&n);
printf("Enter the line\n");
len=getinput(a);
insert_space(a,b,len,n);
printf("%s\n",b);
}
void insert_space(char s1[],char s2[],int len, int n)
{
int i=0, c=0,flag=0;
for(i=0;i<=len;i++)
{
if(flag!=n)
{
s2[c]=s1[i];
c++;
flag++;
}
else
{
s2[c]=' ';
i=i-1;
c++;
flag=0;
}
}
s2[c]='\0';
}
int getinput(char temp[])
{
int c, i=0;
while((c=getchar())!=EOF)
{
temp[i]=c;
i++;
}
i--;
temp[i]='\0';
return i;
}
I entered the values of the string a as abcdefghijkmnop. Instead of
"abdce fghij kmnop" as the ouput in b, I got "abcd efghi jkmno p" as the output. I'm not sure what I did wrong here.
edit: After just including the insert_function code, I've edited it to include the entire execution code.
There is a \n ,newline (Enter) from scanf("%d",&n); which is recorded as a[0]. So you have to manage this UN-handled newline (Enter).
To solve this, add an extra c = getchar(); before loop while ((c = getchar()) != EOF) in function int getinput(char temp[]), to handle that extra newline left behind by scanf("%d",&n);
Modified code:-
#include <stdio.h>
int getinput(char temp[]);
void insert_space(char s1[], char s2[], int, int);
int main()
{
int n, len;
char a[100], b[100];
printf("Enter the nth column number for inserting\n");
scanf("%d", &n);
printf("Enter the line\n");
len = getinput(a);
insert_space(a, b, len, n);
printf("%s\n", b);
}
void insert_space(char s1[], char s2[], int len, int n)
{
int i = 0, c = 0, flag = 0;
for (i = 0; i <= len; i++)
{
if (flag != n)
{
s2[c] = s1[i];
c++;
flag++;
}
else
{
s2[c] = ' ';
i = i - 1;
c++;
flag = 0;
}
}
s2[c] = '\0';
}
int getinput(char temp[])
{
int c, i = 0;
c = getchar(); // to handle extra newline from scanf
while ((c = getchar()) != EOF)
{
temp[i] = c;
i++;
}
i--;
temp[i] = '\0';
return i;
}
Output :-
Enter the nth column number for inserting
5
Enter the line
abcdefghijkmnop
abcde fghij kmnop
Whenever I run the following code, I get the error message
"format specifies type char * but the argument has type int."
The program is supposed to print a n by n square or triangle of a specific character. I'm pretty new to C, and I haven't had much luck troubleshooting this.
#include <stdio.h>
#include <ctype.h>
void print_square(int n, char c) {
for (int i=0; i < n; i++) {
for (int j; j < n; j++) {
printf("%c", c);
}
printf("\n");
}
}
void print_triangle(int n, char c) {
int count = 1;
for (int i=0; i < n; i++) {
for (int j; j < count; j++) {
printf("%c", c);
}
count = count + 1;
printf("\n");
}
}
int main(int argc, const char * argv[]) {
int n;
char cmd;
char * c;
do {
printf("Enter T for a triangle, S for a square, "
"Q to quit: ");
scanf("%c", &cmd);
cmd = toupper(cmd);
if (cmd == 'S' || cmd == 'T') {
printf("Enter the size: ");
scanf("%d", &n);
printf("Enter the character: ");
scanf("%c", *c); // error here
if (cmd == 'S') {
print_square(n, *c);
}
else {
print_triangle(n, *c);
}
}
} while (cmd != 'T' && cmd != 'S' && cmd != 'Q');
return 0;
}
As you've pointed already, the error is indeed in
scanf("%c", *c);
You need to pass a valid pointer to char, why to dereference?
Note: In your case, you're dereferencing an unitialized pointer, which invokes undefined behavior, anyway.
To have a better approach (you dont really need c to be a pointer there) do something like
char c;
scanf(" %c", &c); //the leading space consumes the newline in input bufer
and you should be good to go.
Accordingly, you need to pass c instead of *c, as required in other function calls.
I am trying to input string into fixed size char array.
I have a questions:
when I input a string which is bigger than the char array, the array become bigger without any additional declaration. I want to make the code only take the string that 'equal or smaller than the char array'.
Thank You.
CODE:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
/***************************Function****************************/
int string_length(char s[]) {
int c = 0;
while (s[c] != '\0')
c++;
return c;
}
/**************************************************************/
char *str;
int arrSize;
void opt1()
{
printf("Enter array size: ");
scanf("%d", &arrSize);
arrSize=arrSize+1;
str = malloc(arrSize);
return;
}
void opt2()
{
printf("Enter characters: ");
scanf("%s", str);
length = string_length(str);
printf("your input is '%s'\n", str);
printf("your input length is '%d'\n", length);
return;
}
int main()
{
int input = 0;
while(input != 3) {
printf("\n NAME \n");
printf("\n");
printf("--------------------------------------\n");
printf("1) Making Array \n");
printf("2) Check Array \n");
printf("3) Quit\n");
printf("\nEnter selection: ");
scanf("%d", &input);
if( input == 1 ) {
/* */
opt1();
}
else if(input == 2) {
opt2();
}
}
return 1;
}
OP wants to read data, yet if larger that the target array, then do not change the target array.
// 1: success
// -1 EOF
// 0: Input too long
int read_array(char *buffer, size_t size) {
char tmp[size];
size_t i = 0;
int ch;
while ((ch = fgetc(stdin)) != EOF && ch != '\n') {
if (i < size) {
tmp[i++] = ch;
}
}
if (ch == EOF && i == 0) return EOF;
if (i >= size) return 0; // too many
memcpy(buffer, tmp, i);
buffer[i] = '\0';
return 1;
}
Normally code could use fgets(), but there are corner cases that fail to meet OP goals.
To read in a whole line, you can use fgets:
char line[80];
if (fgets(line, sizeof line, stdin) != NULL) {
// use the input
}
Now you won't need to check if the user entered more than the limit, since fgets will only get the first 79 (-1 for null terminator) characters; the remainder, if any, will be ignored.
So I made a program where I have to input a word and it displays if it is a palindrome (a word that is the same both ways) or not.
#include <stdio.h>
#include <string.h>
int main(int argc, const char * argv[]){
char word;
int length, counter;
printf("Please enter a word: ");
scanf("%c", &word);
int flag = 1;
for (counter = 0; counter < length && flag; counter++) {
printf("%c\t %c", word[counter], word[length - counter])
if (word[counter] == word[length - counter - 1]){
flag = 0;
}
}
if (flag) {
printf("%c is a palindrome!", word);
}
else {
printf("%c is NOT a palindrome!", word);
}
}
I set it up so that it displays each letter side by side. If a letter isn't the same then the flag is "thrown"(set to 0) and this will end the program saying: "word is NOT a palindrome!"
I get an error at the part where it says word[counter] saying it isn't a subscripted value. What can I do to make this work? Is there anything else I am doing wrong?
This char word; is not an array. This char word[100]; is an Array. Also you read a single character using scanf("%c", &word); not a word (as in a string or series of characters). Use:
fgets (word , 100 , stdin)
Also length is not initialized, so it will lead to UB.
Make this modifications in your program.It will run fine.
#include <stdio.h>
#include <string.h>
int main()
{
char word[100];
int length, counter;
printf("Please enter a word: ");
scanf("%s",word);
length=strlen(word);
int flag = 1;
for(counter = 0; counter < length/2 && flag; counter++)
{
if (word[counter] != word[length-counter-1])
{
flag = 0;
break;
}
}
if (flag)
{
printf("%s is a palindrome!\n", word);
}
else {
printf("%s is NOT a palindrome\n!", word);
}
}
****************************************************************
* Simple Array Palindrome Program *
****************************************************************/
#include <iostream>
using namespace std;
int main (){
int arr_size;
int flag=0;
/*****************************************
* Array Size *
*****************************************/
cout<<"Enter The Array Size: \n->arr[";
cin>>arr_size;cout<<" ]";
int arr[arr_size];
/*****************************************
* User_Input *
*****************************************/
for(int i=0;i<arr_size;i++){
cout<<"Enter Value For Arr[ "<<i<<" ] -> ";
cin>>arr[i];
}
/*****************************************
* Palindrome_Check *
*****************************************/
for(int k=0,j=arr_size-1;k<arr_size && j>-1;k++)
{
if(arr[i]==arr[j];
{
flag++;
}
}
/*****************************************
* Flag Check *
*****************************************/
if(flag==arr_size) {
cout<<"Array Is Palindrome: ";
}
else
{
cout<<"Array Is Not Palindrome: ";
}
}