I'm trying to write an ITOA (integer to array) function using pointers.
So this is what I got so far. I debugged and it works just fine. The thing is, the printing itself doesn't work. I'm adding two screenshots.
Would appreciate some help.
int num_length(int number)
{
int count = 0;
while (number > 0)
{
count++;
number /= 10;
}
return count;
}
void itoa(int number, char *strptr)
{
int number_len = num_length(number);
char *start = strptr;
strptr += number_len - 1;
while (strptr >= start)
{
*strptr = number % 10;
number /= 10;
strptr--;
}
}
void print_string(char *strptr)
{
while (*strptr != '\0')
{
printf("%c", *strptr);
strptr++;
}
}
void main(void)
{
int number;
char number_in_string[N] = { '\0' };
char *strptr = &(number_in_string[0]);
printf("Enter a number: ");
scanf_s("%d", &number);
itoa(number, strptr);
print_string(number_in_string);
getch();
}
If you're trying to get an array of numeric characters (as seems evident by your print_string(a) function), you'll need to adjust the values appropriately:
*strptr = number % 10 + '0';
As per your debugging output ('\x2', '\x5', '\x5') , you're correctly getting the individual digits of the number but those are binary values, not the character representations.
Turning the former into the latter involves adding '0' (0x30 if you're using ASCII, for example). C guarantees that the numeric values are contiguous so this is safe.
(a) ... which could, by the way, be replaced with a simple:
printf("%s", number_in_string);
in your main function.
Related
Instruction: Alright, I am working on a code where I am doing number conversions. I am prompting the user to give me a base and an input of bits with a mathematic symbol such as '+', '-', '*' etc, and I do the calculation, if you have a strategy for that, then feel free to give me an idea.
Problem: Regardless, I am working on some strategy on how to do it, but I am having trouble with my character, strings, char pointers. I don't know how to resolve it. I hardly understand what pointers are, besides a location in memory. I need help resolving this problem.
baseToDec Function: Anyways, I have a method/function called baseToDec, where I perform a conversion from bits to a decimal and return an int. Inside those parameters, I have a char* which takes in the value. such as '1001' which is the value 9.
Ways: However, when I put in the string "first" inside that parameter down in my main, I get a fault segmentation. I don't know how to declare that string value where I won't get warnings or a segmentation fault. I've tried changing the variable to be a char *first, I tried to do the address. I don't understand it. I would like to know how I can do it so I don't get a warning and it returns an integer smoothly.
int baseToDec(int base, char* value)
{
int len = strlen(value);
int power = 1, result = 0,i, j, num;
if(base > 2) //not binary
{
for (i = len - 1; i >= 0; i--)
{
result += number(value[i]) * power;
power = power * base;
}
}
else if(base = 2)
{
while(value[i] == '0' || value[i] == '1' )// (2) remove the most significant binary digit(leftmost) and add it to the result.
{
if(value[i] == '1')
{
result = result * 2 + 1;
}
else if(value[i] == '0')
{
result *= 2;
}
i++;
} // (3) If all binary digits have been removed, you're done. Stop.
}
return result;
}
int main()
{
int base, i = 0, j =0, dec; // dec is declared here.
char input[100], first[100], second[100];
char option;
instructions();
scanf("%s", &option);
while(option != 'q')
{
i = 0;
printf("Base: ");
scanf("%d", &base);
printf("Input: ");
scanf("%s", input);
while(input[i] != '+' && input[i] != '-' && input[i] != '*' && input[i] != '/')
{
i++;
}
printf("%d", i);
if(input[i] == '+')
{
for(j = 0; j < i; j++)
{
first[j] = input[j];
}
first[i] = 0;
dec = baseToDec(base, first); // Error takes place here.
}
}
I know it's a lot of writing, but I listed where the errors take place and the method I pass.
This is wrong:
scanf("%s", &option);
When you use %s, you have to provide a pointer to a string that can hold the entire input. option is a char, not a string. It only has room for a single character, but %s writes the input word followed by a null terminator.
Use %c format to read a single character.
scanf(" %c", &option);
Also,
if (base = 2)
should be
if (base == 2)
But there's no need to treat binary differently from any other base, the conversion process is the same.
This is for Homework
I have to write a program that asks the user to enter a string, then my program would separate the even and odd values from the entered string. Here is my program.
#include <stdio.h>
#include <string.h>
int main(void) {
char *str[41];
char odd[21];
char even[21];
int i = 0;
int j = 0;
int k = 0;
printf("Enter a string (40 characters maximum): ");
scanf("%s", &str);
while (&str[i] < 41) {
if (i % 2 == 0) {
odd[j++] = *str[i];
} else {
even[k++] = *str[i];
}
i++;
}
printf("The even string is:%s\n ", even);
printf("The odd string is:%s\n ", odd);
return 0;
}
When I try and compile my program I get two warnings:
For my scanf I get "format '%s' expects arguments of type char but argument has 'char * (*)[41]". I'm not sure what this means but I assume it's because of the array initialization.
On the while loop it gives me the warning that says comparison between pointer and integer. I'm not sure what that means either and I thought it was legal in C to make that comparison.
When I compile the program, I get random characters for both the even and odd string.
Any help would be appreciated!
this declaration is wrong:
char *str[41];
you're declaring 41 uninitialized strings. You want:
char str[41];
then, scanf("%40s" , str);, no & and limit the input size (safety)
then the loop (where your while (str[i]<41) is wrong, it probably ends at once since letters start at 65 (ascii code for "A"). You wanted to test i against 41 but test str[i] against \0 instead, else you get all the garbage after nul-termination char in one of odd or even strings if the string is not exactly 40 bytes long)
while (str[i]) {
if (i % 2 == 0) {
odd[j++] = str[i];
} else {
even[k++] = str[i];
}
i++;
}
if you want to use a pointer (assignement requirement), just define str as before:
char str[41];
scan the input value on it as indicated above, then point on it:
char *p = str;
And now that you defined a pointer on a buffer, if you're required to use deference instead of index access you can do:
while (*p) { // test end of string termination
if (i % 2 == 0) { // if ((p-str) % 2 == 0) { would allow to get rid of i
odd[j++] = *p;
} else {
even[k++] = *p;
}
p++;
i++;
}
(we have to increase i for the even/odd test, or we would have to test p-str evenness)
aaaand last classical mistake (thanks to last-minute comments), even & odd aren't null terminated so the risk of getting garbage at the end when printing them, you need:
even[k] = odd[j] = '\0';
(as another answer states, check the concept of even & odd, the expected result may be the other way round)
There are multiple problems in your code:
You define an array of pointers char *str[41], not an array of char.
You should pass the array to scanf instead of its address: When passed to a function, an array decays into a pointer to its first element.
You should limit the number of characters read by scanf.
You should iterate until the end of the string, not on all elements of the array, especially with (&str[i] < 41) that compares the address of the ith element with the value 41, which is meaningless. The end of the string is the null terminator which can be tested with (str[i] != '\0').
You should read the characters from str with str[i].
You should null terminate the even and odd arrays.
Here is a modified version:
#include <stdio.h>
int main(void) {
char str[41];
char odd[21];
char even[21];
int i = 0;
int j = 0;
int k = 0;
printf("Enter a string (40 characters maximum): ");
if (scanf("%40s", str) != 1)
return 1;
while (str[i] != '\0') {
if (i % 2 == 0) {
odd[j++] = str[i];
} else {
even[k++] = str[i];
}
i++;
}
odd[j] = even[k] = '\0';
printf("The even string is: %s\n", even);
printf("The odd string is: %s\n", odd);
return 0;
}
Note that your interpretation of even and odd characters assumes 1-based offsets, ie: the first character is an odd character. This is not consistent with the C approach where an even characters would be interpreted as having en even offset from the beginning of the string, starting at 0.
Many answers all ready point out the original code`s problems.
Below are some ideas to reduce memory usage as the 2 arrays odd[], even[] are not needed.
As the "even" characters are seen, print them out.
As the "odd" characters are seen, move them to the first part of the array.
Alternative print: If code used "%.*s", the array does not need a null character termination.
#include <stdio.h>
#include <string.h>
int main(void) {
char str[41];
printf("Enter a string (40 characters maximum): ");
fflush(stdout);
if (scanf("%40s", str) == 1) {
int i;
printf("The even string is:");
for (i = 0; str[i]; i++) {
if (i % 2 == 0) {
str[i / 2] = str[i]; // copy character to an earlier part of `str[]`
} else {
putchar(str[i]);
}
}
printf("\n");
printf("The odd string is:%.*s\n ", (i + 1) / 2, str);
}
return 0;
}
or simply
printf("The even string is:");
for (int i = 0; str[i]; i++) {
if (i % 2 != 0) {
putchar(str[i]);
}
}
printf("\n");
printf("The odd string is:");
for (int i = 0; str[i]; i++) {
if (i % 2 == 0) {
putchar(str[i]);
}
}
printf("\n");
here is your solution :)
#include <stdio.h>
#include <string.h>
int main(void)
{
char str[41];
char odd[21];
char even[21];
int i = 0;
int j = 0;
int k = 0;
printf("Enter a string (40 characters maximum): ");
scanf("%s" , str);
while (i < strlen(str))
{
if (i % 2 == 0) {
odd[j++] = str[i];
} else {
even[k++] = str[i];
}
i++;
}
odd[j] = '\0';
even[k] = '\0';
printf("The even string is:%s\n " , even);
printf("The odd string is:%s\n " , odd);
return 0;
}
solved the mistake in the declaration, the scanning string value, condition of the while loop and assignment of element of array. :)
I'm trying to write a program that gets a string, and a number, and calculates the length of it and shifting all the elents right.
I have 2 errors:
1.assignment makes pointer from integer without a cast.
2.assignment makes integer from pointer without a cast.
#include <stdio.h>
#include <string.h>
#define N 10
int myStrlen(char*);
void shiftRight(char*, int);
int main() {
char str[N] = {0};
int num = 0;
int len;
/* input of the string */
scanf("%s",str);
scanf("%d",&num);
len=myStrlen(str);
if(num>=0) {
shiftRight(str, num);
printf("%s\n",str);
}
else
{
printf("%s\n", str);
}
return 0;
}
int myStrlen(char*str)
{
int my_len=0;
while (str[my_len] != '\0')
{
my_len++;
}
return my_len;
}
void shiftRight(char* str, int num)
{
int i;
char* j;
int count;
j=(str[N-1]);
for(count=0;count<num;count++)
{
for(i=N-1;i>0;--i)
{
str[i]=str[i-1];
}
str[0]=j;
}
}
Your answers are welcome,anf if you anything wrong with this code,please mention it.
As your compiler will have told you, pointer from integer without a cast is at
j=(str[N-1]);
And integer from pointer is at
str[0]=j;
You should have declared j as char j;
But now when i run it, and typing lets say ball as a string and 1 to
be a number, i get nothing from the program instead of getting "lbal"
You have all the correct elements but that's not enough. Writing a program is telling a story, you need to set the scene, describe what happens along the way and conclude your narrative. A story with elements out of order is nonsense, as is a program.
Specific issues with your code: you're saving of the last character (to restore it to the beginning of the string) is in the wrong place; you're using the allocation of the string when you should be using it's length (and conveniently, you have a function for that!); this is really more of a rotation than a shift; use the most descriptive variable names you can, not the shortest you can get away with; pick one indentation style and stick with it -- it can change between programs you write but shouldn't change within an individual program.
Below is a rework of your code addressing some of the issues above:
#include <stdio.h>
#define STRING_SIZE 10
int myStrlen(char *string)
{
int length = 0;
while (string[length] != '\0')
{
length++;
}
return length;
}
void rotateRight(char *string, int number)
{
int length = myStrlen(string);
for (int count = 0; count < number; count++)
{
char j = string[length - 1];
for (int i = length - 1; i > 0; i--)
{
string[i] = string[i - 1];
}
string[0] = j;
}
}
int main()
{
char string[STRING_SIZE] = {0};
int number = 0;
/* input of the string */
scanf("%s", string);
scanf("%d", &number);
if (number > 0)
{
rotateRight(string, number);
printf("%s\n", string);
}
else
{
printf("%s\n", string);
}
return 0;
}
OUTPUT
% ./a.out
elephant
3
anteleph
%
The question is that show the digits which were repeated in C.
So I wrote this:
#include<stdio.h>
#include<stdbool.h>
int main(void){
bool number[10] = { false };
int digit;
long n;
printf("Enter a number: ");
scanf("%ld", &n);
printf("Repeated digit(s): ");
while (n > 0)
{
digit = n % 10;
if (number[digit] == true)
{
printf("%d ", digit);
}
number[digit] = true;
n /= 10;
}
return 0;
}
But it will show the repeated digits again and again
(ex. input: 55544 output: 455)
I revised it:
#include<stdio.h>
int main(void){
int number[10] = { 0 };
int digit;
long n;
printf("Enter a number: ");
scanf("%ld", &n);
printf("Repeated digit(s): ");
while (n > 0)
{
digit = n % 10;
if (number[digit] == 1)
{
printf("%d ", digit);
number[digit] = 2;
}
else if (number[digit] == 2)
break;
else number[digit] = 1;
n /= 10;
}
return 0;
}
It works!
However, I want to know how to do if I need to use boolean (true false), or some more efficient way?
To make your first version work, you'll need to keep track of two things:
Have you already seen this digit? (To detect duplicates)
Have you already printed it out? (To only output duplicates once)
So something like:
bool seen[10] = { false };
bool output[10] = { false };
// [...]
digit = ...;
if (seen[digit]) {
if (output[digit])) {
// duplicate, but we already printed it
} else {
// need to print it and set output to true
}
} else {
// set seen to true
}
(Once you've got that working, you can simplify the ifs. Only one is needed if you combine the two tests.)
Your second version is nearly there, but too complex. All you need to do is:
Add one to the counter for that digit every time you see it
Print the number only if the counter is exactly two.
digit = ...;
counter[digit]++;
if (counter[digit] == 2) {
// this is the second time we see this digit
// so print it out
}
n = ...;
Side benefit is that you get the count for each digit at the end.
Your second version code is not correct. You should yourself figured it out where are you wrong. You can try the below code to print the repeated elements.
#include<stdio.h>
int main(void){
int number[10] = { 0 };
int digit;
long n;
printf("Enter a number: ");
scanf("%ld", &n);
printf("Repeated digit(s): ");
while (n > 0)
{
digit = n % 10;
if (number[digit] > 0)
{
number[digit]++;;
}
else if (number[digit] ==0 )
number[digit] = 1;
n /= 10;
}
int i=0;
for(;i<10; i++){
if(number[i]>0)
printf("%d ", i);
}
return 0;
}
In case you want to print the repeated element using bool array (first version) then it will print the elements number of times elements occur-1 times and in reverse order because you are detaching the digits from the end of number , as you are seeing in your first version code output. In case you want to print only once then you have to use int array as in above code.
It is probably much easier to handle all the input as strings:
#include <stdio.h>
#include <string.h>
int main (void) {
char str[256] = { 0 }; /* string to read */
char rep[256] = { 0 }; /* string to hold repeated digits */
int ri = 0; /* repeated digit index */
char *p = str; /* pointer to use with str */
printf ("\nEnter a number: ");
scanf ("%[^\n]s", str);
while (*p) /* for every character in string */
{
if (*(p + 1) && strchr (p + 1, *p)) /* test if remaining chars match */
if (!strchr(rep, *p)) /* test if already marked as dup */
rep[ri++] = *p; /* if not add it to string */
p++; /* increment pointer to next char */
}
printf ("\n Repeated digit(s): %s\n\n", rep);
return 0;
}
Note: you can also add a further test to limit to digits only with if (*p >= '0' && *p <= '9')
output:
$./bin/dupdigits
Enter a number: 1112223334566
Repeated digit(s): 1236
Error is here
if (number[digit] == true)
should be
if (number[digit] == false)
Eclipse + CDT plugin + stepping debug - help you next time
As everyone has given the solution: You can achieve this using the counting sort see here. Time complexity of solution will be O(n) and space complexity will be O(n+k) where k is the range in number.
However you can achieve the same by taking the XOR operation of each element with other and in case you got a XOR b as zero then its means the repeated number. But, the time complexity will be: O(n^2).
#include <stdio.h>
#define SIZE 10
main()
{
int num[SIZE] = {2,1,5,4,7,1,4,2,8,0};
int i=0, j=0;
for (i=0; i< SIZE; i++ ){
for (j=i+1; j< SIZE; j++){
if((num[i]^num[j]) == 0){
printf("Repeated element: %d\n", num[i]);
break;
}
}
}
}
I need to get the number of digits containing the number 1. I know in java I can take the input as a String and use charAt, but I understand there is no implicit String function in C. How can I accomplish this?
Division and modulus are your friends.
#include "stdio.h"
int main(){
int digits[] = {0,0,0,0,0,0,0,0,0,0};
int i = 11031;
while(i > 0){
digits[i % 10]++;
i = i / 10;
}
printf("There are %d ones.\n", digits[1]);
}
Homework?
You'd read it into a char* using the fread() function, and then store how many bytes were read in a separate variable. Then use a for loop to iterate through the buffer and count how many of each byte are present.
Try something like...
int digit = 0;
int value = 11031;
while(value > 0)
{
digit = value % 10;
/* Do something with digit... */
value = value / 10;
}
I see this as a basic understanding problem, which inevitably everyone goes through switching from one language to the next.
A good reference to go through to understand how string's work in C when you've started familiarity with java is look at how string.h works. Where as in java string's are an Object and built in, strings in C are just integer arrays.
There are a lot of tutorials out there, one that helped me when I was starting earlier in the year was http://www.physics.drexel.edu/students/courses/Comp_Phys/General/C_basics/ look at the string section.
Sometimes asking a question speeds up learning a lot faster than pouring through the text book for hours on end.
If you have just the number, then you can do this:
int val; //Input
...
int ones = 0;
while(val != 0) {
ones += ((val % 10) == 1) ? 1 : 0;
val /= 10;
}
If you have a string (char*), the you'd do something like this:
while(*str != '\0') {
if(*str++ == '1') {
ones++;
}
}
It's also worth noting that c does have a charAt function, in a way:
"java".charAt(i) == "c the language"[i];
By indexing into the char*, you can get the value you want, but you need to be careful, because there is no indexOutOfBounds exception. The program will crash if you go over the end of a string, or worse it may continue running, but have a messed up internal state.
Something along the lines of:
int val=11031;
int count=0;
int i=0;
char buf[100];
sprint(buf, "%d", val);
for(i=0; (i < sizeof(buf)) && (buf[i]); i++) {
if(buf[i] == '1')
count++;
}
int count_digit(int nr, int digit) {
int count=0;
while(nr>0) {
if(nr%10==digit)
count++;
nr=nr/10;
}
return count;
}
This sounds like a homework problem to me. Oh well, it's your life.
You failed to specify the type of the variable that contains the "input integer". If the input integer is an integral type (say, an "int") try this:
int countOnes(int input)
{
int result = 0;
while(input) {
result += ((input%10)==1);
result /= 10;
}
return result;
}
If the "input integer" is in a string, try this:
int countOnes(char *input)
{
int result = 0;
while(input && *input) {
result += (*input++ == '1');
}
return result;
}
Hope this helps. Next time, do your own homework. And get off of my lawn! Kids, these days, ...
int countDigit(int Number, int Digit)
{
int counter = 0;
do
{
if( (Number%10) == Digit)
{
counter++;
}
}while(Digit>0)
return counter;
}
Something along the lines of this:
#include <stdio.h>
main() {
char buf[100];
char *p = buf;
int n = 0;
scanf("%s", buf);
while (*p) {
if (*p == '1') {
n++;
}
p++;
}
printf ("'%s' contains %i ones\n", buf, n);
}
This will do it. :-)
int count_digits(int n, int d) {
int count = 0;
while(n*10/=10) if (n%10==d) count++
return count;
}
For all those who refer to the question as the homework question: I have to say, most of you provided a homework answer.
You don't do division/modulus to get the digits in production code, firstly because it's suboptimal (your CPU is designed for binary arithmetics not decimal) and secondly because it's unintuitive. Even if it's not originally a string, it's more optimal to convert it to one and then count the characters (std::count is the way to go in C++).