While doing reverse program in C,I am getting issue with number 01 & 10 because its reverse is not showing in the output. Here is my code:
#include<stdio.h>
int main(){
int i,n,rev=0;
printf("Enter the number:");
scanf("%d",&n);
while(n>0){
i=n%10;
rev=rev*10+i;
n=n/10;
}
printf("Reverse of that number:%d",rev);
return 0;
}
I am expecting that if I give 01 as input, its reverse must be shown as 10.
If obliged to still use "%d":
Detect the input offset with "%n", which stores the character offset of the scan at that point.
int offset1 = 0;
int offset2 = 0;
if (scanf(" %n%d%n", &offset1, &n, &offset2) == 1) {
while (offset1 < offset2) {
offset1++;
i = n%10;
rev = rev*10+i;
n = n/10;
}
offset2 - offset1 will be the character count of the number and input "01" has a character count of 2.
This still gets fooled if the text input includes a sign character. Additional, and not so clear, code needed to handle that.
As suggested in comments, this is trivial if approached from a string perspective.
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char input[100] = {0};
if (scanf("%99s", input) != 1) {
printf("Invalid input.\n");
return 1;
}
size_t len = strlen(input);
char *output = malloc(len + 1);
size_t i;
for (i = 0; i < len; i++) {
output[i] = input[len-i-1];
}
output[i] = '\0';
printf("%s\n", output);
free(output);
return 0;
}
You could add in validation code that determines that the input actually is a valid integer, and if you actually need an int back, there are library functions like strtol that will accomplish this.
Related
#include <stdio.h>
#include <string.h>
void main(void)
{
char in[15], rev[15];
printf("Enter a word (upto 15 letters): ");
gets(in);
for (int i = 0, j = 15; i < strlen(in); i++, j--)
{
rev[i] = in[j];
}
puts(rev);
}
Shows no error, just not working.
What am I doing wrong?
Edit : no strrev
For starters according to the C Standard the function main without parameters shall be declared like
int main( void )
The function gets is unsafe and is not supported by the C Standard. Instead use either scanf or fgets.
The function strlen is a standard C string function. So according to the requirement you may not use it.
You are not reversing a string. You are trying to copy a string in the reverse order into another string.
The program can look the following way
#include <stdio.h>
int main(void)
{
enum { N = 15 };
char in[N] = "", rev[N];
printf("Enter a word (upto %d letters): ", N - 1 );
scanf( " %14s", in );
size_t n = 0;
while ( in[n] ) ++n;
rev[n] = '\0';
for ( size_t i = 0; i < n; i++ )
{
rev[n - i - 1] = in[i];
}
puts( rev );
}
If you actually need to reverse a string in place then the program can look the following way
#include <stdio.h>
int main(void)
{
enum { N = 15 };
char in[N] = "";
printf("Enter a word (upto %d letters): ", N - 1 );
scanf( " %14s", in );
size_t n = 0;
while ( in[n] ) ++n;
for ( size_t i = 0; i < n / 2; i++ )
{
char c = in[i];
in[i] = in[n - i - 1];
in[n - i - 1] = c;
}
puts( in );
}
EDIT: getline is not standard C, and it is only recognized by POSIX systems. Another solution is to use fgets that works for both OSes. I provided both examples.
As others have already pointed out, you are making some mistakes:
Unsafe practice when getting input from the user.
Always starting from 15 even if the input string has less chars.
I have created a little example with dynamic allocation that works with more than 15 characters and fixes the afore-mentioned issues. Comments inline to key points.
Example: getline - POSIX
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[]) {
// Idea from https://stackoverflow.com/questions/7709452/how-to-read-string-from-keyboard-using-c
char *line = NULL; /* forces getline to allocate with malloc */
size_t len = 0; /* ignored when line = NULL */
ssize_t read;
read = getline(&line, &len, stdin);
if (read > 0)
{
printf ("\n String from user: %s\n", line);
}else
{
printf ("Nothing read.. \n");
return -1;
}
// Now we need the same amount of byte to hold the reversed string
char* rev_line = (char*)malloc(read);
// "read-1" because we start counting from 0.
for (int i = 0, j = read-1; i < read; i++, j--)
{
rev_line[i] = line[j];
}
printf("%s\n",rev_line);
free (line); /* free memory allocated by getline */
free(rev_line);
return 0;
}
Example: fgets - C standard
fgets does not return the number of characters read, so it has to be chained with strlen to decide how many characters to allocate for the reversed string.
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
int main (int argc, char *argv[]) {
char line[LINE_MAX];
size_t len = 0; /* ignored when line = NULL */
ssize_t read;
if (fgets(line, LINE_MAX, stdin) != NULL)
{
line[strcspn(line, "\n")] = '\0'; //fgets() reads the \n character (that's when you press Enter).
read = strlen(line);
printf ("\n String from user: %s\n", line);
}else
{
printf ("Nothing read.. \n");
return -1;
}
// Now we need the same amount of byte to hold the reversed string
char* rev_line = (char*)malloc(read);
for (int i = 0, j = read-1; i < read; i++, j--)
{
rev_line[i] = line[j];
}
printf("%s\n",rev_line);
free(rev_line);
return 0;
}
I am self teaching C programming.
I am trying to count number of int present in given string which are separated by space.
exp:
input str = "1 2 11 84384 0 212"
output should be: 1, 2, 11, 84384, 0, 212
total int = 6
When I try. It gives me all the digits as output which make sense since I am not using a right approach here.
I know in python I can use str.split (" ") function which can do my job very quickly.
But I want to try something similar in C. Trying to create my own split method.
#include <stdio.h>
#include <string.h>
void count_get_ints(const char *data) {
int buf[10000];
int cnt = 0, j=0;
for (int i=0; i<strlen(data); i++) {
if (isspace(data[i] == false)
buf[j] = data[i]-'0';
j++;
}
printf("%d", j);
}
// when I check the buffer it includes all the digits of the numbers.
// i.e for my example.
// buf = {1,2,1,1,8,4,3,8,4,0,2,1,2}
// I want buf to be following
// buf = {1,2,11,84384,0,212}
I know this is not a right approach to solve this problem. One way to keep track of prev and dynamically create a memory using number of non space digits encountered.
But I am not sure if that approach helps.
You want to build your number incrementally until you hit a space, then put that into the array. You can do this by multiplying by 10 then adding the next digit each time.
void count_get_ints(const char *data) {
int buf[10000];
int j = 0;
int current_number = 0;
// Move this outside the loop to eliminate recalculating the length each time
int total_length = strlen(data);
for (int i=0; i <= total_length; i++) {
// Go up to 1 character past the length so you
// capture the last number as well
if (i == total_length || isspace(data[i])) {
// Save the number, and reset it
buf[j++] = current_number;
current_number = 0;
}
else {
current_number *= 10;
current_number += data[i] - '0';
}
}
}
I think strtok will provide a cleaner solution, unless you really want to iterate over every char in the string. It has been a while since I did C, so please excuse any errors in the code below, hopefully it will give you the right idea.
#include <stdio.h>
#include <stdlib.h>
int main() {
char str[19] = "1 2 11 84384 0 212";
const char s[2] = " ";
char *token;
int total;
total = 0;
token = strtok(str, s);
while (token != NULL) {
printf("%s\n", token);
total += atoi(token);
token = strtok(NULL, s);
}
printf("%d\n", total);
return 0;
}
You can check the ascii value of each character by doing c-'0'. If it's between [0,9], then it's an integer. By having a state variable, when you're inside an integer by checking if a given character is a number of space, you can keep track of the count by ignoring white space. Plus you don't need a buffer, what happens if data is larger than 10,000, and you write pass the end of the buffer?, undefined behavior will happen. This solution doesn't require a buffer.
Edit, the solution now prints the integers that are in the string
void count_get_ints(const char *data) {
int count = 0;
int state = 0;
int start = 0;
int end = 0;
for(int i = 0; i<strlen(data); i++){
int ascii = data[i]-'0';
if(ascii >= 0 && ascii <= 9){
if(state == 0){
start = i;
}
state = 1;
}else{
//Detected a whitespace
if(state == 1){
count++;
state = 0;
end = i;
//Print the integer from the start to end spot in data
for(int j = start; j<end; j++){
printf("%c",data[j]);
}
printf(" ");
}
}
}
//Check end
if(state == 1){
count++;
for(int j = start; j<strlen(data); j++){
printf("%c",data[j]);
}
printf(" ");
}
printf("Number of integers %d\n",count);
}
I believe the standard way of doing this would be using sscanf using the %n format specifier to keep track of how much of the string is read.
You can start with a large array to read into -
int array[100];
Then you can keep reading integers from the string till you can't read anymore or you are done reading 100.
int total = 0;
int cont = 0;
int ret = 1;
while(ret == 1 && total < 100) {
ret = sscanf(input, "%d%n", &array[total++], &cont);
input += cont;
}
total--;
printf("Total read = %d\n", total);
and array contains all the numbers read.
Here is the DEMO
Example using strtol
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
#include <ctype.h>
int count_get_ints(int output[], int output_size, const char *input) {
const char *p = input;
int cnt;
for(cnt = 0; cnt < output_size && *p; ++cnt){
char *endp;
long n;
errno = 0;
n = strtol(p, &endp, 10);
if(errno == 0 && (isspace((unsigned char)*endp) || !*endp) && INT_MIN <= n && n <= INT_MAX){
output[cnt] = n;
while(isspace((unsigned char)*endp))
++endp;//skip spaces
p = endp;//next parse point
} else {
fprintf(stderr, "invalid input '%s' in %s\n", p, __func__);
break;
}
}
return cnt;
}
int main(void) {
const char *input = "1 2 11 84384 0 212";
int data[10000];
int n = sizeof(data)/sizeof(*data);//number of elements of data
n = count_get_ints(data, n, input);
for(int i = 0; i < n; ++i){
if(i)
printf(", ");
printf("%d", data[i]);
}
puts("");
}
Assuming you don't have any non-numbers in your string, you can just count the number of spaces + 1 to find the number of integers in the string like so in this pseudo code:
for(i = 0; i < length of string; i++) {
if (string x[i] == " ") {
Add y to the list of strings
string y = "";
counter++;
}
string y += string x[i]
}
numberOfIntegers = counter + 1;
Also, this reads the data between the white spaces. Keep in mind this is pseudo code, so the syntax is different.
I'm trying to turn an int into string. I did it so far by getting the int with scanf, and then split it according to it's digits, and then put every one of the digits inside int array. Then I want to put all the int arr values inside a string, where the sign + or - will be the first character. Here is my code:
#include <stdio.h>
#include <string.h>
#define LENGTH 50
int getLength(int num, int arr[]);
int main()
{
int num = 0, i = 0;
int arr[LENGTH] = {0};
char string[LENGTH] = {0};
printf("enter number: ");
scanf("%d", &num);
int sizeMe = getLength(num, arr);
string[2] = arr[2] + '0';
printf("length %d one of values: %c", sizeMe,string[2]);
for(i = 1; i < sizeMe + 1; i++);
{
string[i] = arr[sizeMe - i] + '0';
}
string[0] = '+';
string[sizeMe] = 0;
printf("string: %s", string);
}
int getLength(int num,int arr[])
{
int count = 0;
int i = 0, temp = 0;
while(num != 0)
{
temp = num%10;
num /= 10;
count++;
i++;
arr[i] = temp;
printf("index %d is %d\n",i,arr[i]);
}
return count;
}
The output of that program is just '+'. What did I do wrong here?
The problem that is causing your code not to work is that you have a semicolon after the for statement like this:
for(i = 1; i < sizeMe + 1; i++);
{
string[i] = arr[sizeMe - i] + '0';
}
That code would be equivalent to this:
for(i = 1; i < sizeMe + 1; i++){}
string[i] = arr[sizeMe - i] + '0';
So what's happening there is that only the last element of string is written in, the rest is left blank, which generates undefined behavior. To solve the problem, remove the semicolon. I also recommend putting the { at the end of the line of the for statement instead of on a new line since doing so would prevent you from making such mistakes. This is therefore the correct code, formatted in the way that I recommend formatting:
for(i = 1; i < sizeMe + 1; i++){
string[i] = arr[sizeMe - i + 1] + '0';
}
Note that you also forgot the +1 in arr[sizeMe - i + 1].
Although that was the error that made your code not work the way you wanted it to work, you've also made several other mistakes, which could potentially cause your program to crash.
First of all, in the for loop, you're not testing if i is greater than LENGTH. The problem with that is that if i is greater than LENGTH, string[i] will be outside of the array, which will cause buffer overflow and make your program crash. To solve this problem, add the following code inside your for loop:
if(i + 1 > LENGTH){
break;
}
The break statement will exit the for loop immediately. Note that we're testing if i + 1 is greater than LENGTH to leave space for the null character at the end of the string.
For the same reason, string[sizeMe] = 0; is also bad, since nothing says that sizeMe is less than the size of the array. Instead, use string[i] = 0;, since i has been incremented until it either reaches LENGTH or sizeMe. Therefore, i will be the minimum of these two values, which is what we want.
You also need to return something at the end of the main function. The main function is of type int, so it should return an int. In C++, this code wouldn't compile because of that. Your code compiled since you're using C and C compilers are generally more tolerant than C++ compilers, so you only got a warning. Make sure to fix all compiler warnings, since doing so can solve bugs. The warnings are there to help you, not to annoy you. Generally, the main function should return 0, since this value usually means that everything went well. So you need to add return 0; at the end of the main function.
Therefore, this is the code you should use:
#include <stdio.h>
#include <string.h>
#define LENGTH 50
int getLength(int num, int arr[]);
int main(){
int num = 0, i = 0;
int arr[LENGTH] = {0};
char string[LENGTH] = {0};
printf("enter number: ");
scanf("%d", &num);
int sizeMe = getLength(num, arr);
string[2] = arr[2] + '0';
printf("length %d one of values: %c", sizeMe,string[2]);
for(i = 1; i < sizeMe + 1; i++){
string[i] = arr[sizeMe - i + 1] + '0';
if(i + 1 > LENGTH){
break;
}
}
string[0] = '+';
string[i] = 0;
printf("string: %s", string);
return 0;
}
int getLength(int num,int arr[]){
int count = 0;
int i = 0, temp = 0;
while(num != 0){
temp = num%10;
num /= 10;
count++;
i++;
arr[i] = temp;
printf("index %d is %d\n",i,arr[i]);
}
return count;
}
Also, as some programmer dude pointed out in a comment, it's much easier to use sprintf. Then your code would be much simpler:
#include <stdio.h>
#include <string.h>
#define LENGTH 50
int main(){
int num = 0;
char string[LENGTH] = {0};
printf("enter number: ");
scanf("%d", &num);
sprintf(string, "%c%d", num >= 0 ? '+' : '-', num);
printf("string: %s", string);
return 0;
}
The short answer to turning a C int into a decimal string is to call sprintf(). That leads to the question how sprintf() does it.
From the book The C Programming Language, 2nd edition section 3.6. There is an example of a function that return a string representation of an integer. So here is the code:
void numberToString(int n, char *s){
int i, sign;
if ((sign = n) < 0) /*record sign*/
n = -n; /* make n positive */
i = 0;
do { // generate digits in reverse order
s[i++] = n % 10 + '0'; // get next digit*/
} while ((n /= 10) > 0); // delete it
s[i++] = sign < 0? '-': '+'; // or -- if(sign < 0) s[i++] = '-'; -- if you want just the sign '-'
s[i] = '\0';
strrev(s); //reverse the string
}
int main()
{
int n;
char str[LENGTH];
printf("Number: ");
scanf("%i", &n);
numberToString(n, str);
printf("Number as string: %s\n", str);
}
strrev is defined in the string.h header (so include it).
You can try and do this with sprintf. When you calculate the number length from get_length(), you can declare a string buffer, either statically or dynamically. Once declared, you can send the formatted output in the buffer with sprintf().
However, if you wish to still use your approach, #Donald Duck has covered the issues into debugging your code, and this is just another approach you can use if you want to.
Here is an example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
size_t get_length(int number);
int main(void) {
int number;
size_t numcnt;
char *string;
printf("Enter number: ");
if (scanf("%d", &number) != 1) {
printf("Invalid number entered\n");
exit(EXIT_FAILURE);
}
printf("Number = %d\n", number);
numcnt = get_length(number);
string = malloc(numcnt+1);
if (!string) {
printf("Cannot allocate %zu bytes for string\n", numcnt+1);
exit(EXIT_FAILURE);
}
sprintf(string, "%d", number);
printf("String = %s\n", string);
free(string);
return 0;
}
size_t get_length(int number) {
size_t count = 0;
if (number < 0) {
number *= -1;
count++;
}
for (size_t i = number; i > 0; i /= 10) {
count++;
}
return count;
}
Sample input 1:
Enter number: 1234
Sample output 1:
Number = 1234
String = 1234
Sample input 2:
Enter number: -1234
Sample output 2:
Number = -1234
String = -1234
I have this code. The user should input something like this "10.0 10.0 4.0 7.0". And, I want my program to put these floating point numbers into an array so that each of these is accessible through floats[0] = 10.0, floats[1] = 10.0 floats[2] = 4.0 floats[3] = 7.0. I would make them floating point types later. In this code I'm trying to use two-dimensional array, but something is definitely wrong.
Can you put me on the right track?
#include <cs50.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
int main(void)
{
// prompt the user to enter two inputs
string input1 = get_string();
// declare and initialize essential variables
int len1 = strlen(input1);
int j = 0;
// declare an array where the next lines of code should put floats separately
string floats[100][100];
// put each floating point number into an array character by character
for (int i = 0; i < len1; i++) {
if (isspace(input1[i])) {
j++;
} else {
floats[j][i] = input1[i];
}
}
}
strtod() is the best tool for parsing floating point numbers.
To separate sub-strings using whitespace, at a minimum OP's code is not appending a needed null character. Further the copying from input1[] needs to copy more than just one character.
// Avoid magic numbers, using define self-documents the code
#define FLOAT_STRING_SIZE 100
#define FLOAT_STRING_N 100
int main(void) {
string floats[FLOAT_STRING_N][FLOAT_STRING_SIZE];
string input1 = get_string();
char *p = input1;
int count;
for (count = 0; count < FLOAT_STRING_N; count++) {
while (isspace((unsigned char) *p) p++;
// no more
if (*p == '\0') break;
int i;
for (i = 0; i<FLOAT_STRING_SIZE-1; i++) {
if (isspace((unsigned char) *p) || *p == '\0') break;
floats[count][i] = *p++; // save character and advance to next one.
}
floats[count][i] = '\0';
}
int count;
for (int c = 0; c < count; c++) {
puts(floats[c]);
}
return 0;
}
You can use stringstream (although that's a c++ way) like this
std::stringstream ss;
ss.str (input1);
int i = 0;
string t;
while ( ss >> t)
{
floats[i++] = std::stof(t); //fill your array one by one
}
For pure C way, you can use sscanf.
You can use strtod() to parse the string one floating point number at a time:
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
// prompt the user to enter two inputs
char *input1 = get_string();
// declare the destination array for the floating point numbers
double numbers[100];
int n;
char *p = input1;
char *q;
for (n = 0; n < 100; n++) {
numbers[n] = strtod(p, &q);
if (p == q) {
// no more numbers to parse
break;
}
p = q;
}
// print the array contents
for (int i = 0; i < n; i++) {
printf("%f\n", numbers[i]);
}
return 0;
}
Codechef isn't accepting the following code. Can anyone tell me what's wrong in it as I'm unable to point any mistake ?
//This program reverses a given integer.
#include<stdio.h>
int main(void)
{
int t,n,l;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
while(n>0){
l=n%10;
n=n/10;
printf("%d",l);
}
printf("\n");
}
return 0;
}
t is no. of test cases.
n is the input integer.
l is some random variable to get the print job done.
This program is supposed to reverse a positive integer only.
Example:- Input - 1234
Output - 4321
try this code (I'm agree with molbdnilo's comment):
//This program reverses a given integer.
#include<stdio.h>
#include <math.h>
int main(void)
{
int i,j,t,n,l,r = 0;
char d[1024]; // stock digits
scanf("%d",&t);
while(t--){
scanf("%d",&n);
i = 0;
while(n>0){
l=n%10;
n=n/10;
d[i] = l;
i++;
}
for(j=0;j<i;j++)
r+= d[i-j-1] * pow(10,j); // r is the reversed number
printf("%d\n",r);
}
return 0;
}
I got it. You must not print the non-significant '0'. For example 1230 gives 321. Here is my working code:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/* strrev reverses a given string */
char *strrev(char *str)
{
char tmp;
size_t i = 0,
len = strlen(str);
for (; i < len / 2 ; ++i)
{
tmp = str[i];
str[i] = str[len - i - 1];
str[len - i - 1] = tmp;
}
return str;
}
int main(void)
{
char buff[32],
*s;
size_t i,
len;
scanf("%zu", &len);
for (i = 0 ; i < len ; ++i)
{
scanf("%s", buff);
s = strrev(buff);
while (*s == '0')
++s; /* discarding '0' */
printf("%s\n", s);
}
return EXIT_SUCCESS;
}