I know it's a little unorthodox and will probably cost me some downvotes, but since it's due in 1 hour and I have no idea where to begin I thought I'd ask you guys.
Basically I'm presented with a string that contains placeholders in + form, for example:
1+2+5
I have to create a function to print out all the possibilities of placing different combinations of any given series of digits. I.e. for the series:
[9,8,6] // string array
The output will be
16265
16285
16295
18265
18285
18295
19265
19285
19295
So for each input I get (number of digits)^(number of placeholders) lines of output.
Digits are 0-9 and the maximum form of the digits string is [0,1,2,3,4,5,6,7,8,9].
The original string can have many placeholders (as you'd expect the output can get VERY lengthly).
I have to do it in C, preferably with no recursion. Again I really appreciate any help, couldn't be more thankful right now.
If you can offer an idea, a simplified way to look at solving this, even in a different language or recursively, it'd still be ok, I could use a general concept and move on from there.
It prints them in different order, but it does not matter. and it's not recursive.
#include <stdlib.h>
#include <stdio.h>
int // 0 if no more.
get_string(char* s, const char* spare_chr, int spare_cnt, int comb_num){
for (; *s; s++){
if (*s != '+') continue;
*s = spare_chr[comb_num % spare_cnt];
comb_num /= spare_cnt;
};
return !comb_num;
};
int main(){
const char* spare_str = "986";
int num = 0;
while (1){
char str[] = "1+2+5";
if (!get_string(str, spare_str, strlen(spare_str), num++))
break; // done
printf("str num %2d: %s\n", num, str);
};
return 0;
};
In order to do the actual replacement, you can use strchr to find the first occurrence of a character and return a char * pointer to it. You can then simply change that pointer's value and bam, you've done a character replacement.
Because strchr searches for the first occurrence (before a null terminator), you can use it repeatedly for every value you want to replace.
The loop's a little trickier, but let's see what you make of this.
Related
i'm trying to get a 2 strings from the user and the second one will be the "needle" to copy to the first string
for example:
string 1 (user input): eight height freight
string 2 (user input): eight
output: EIGHT hEIGHT frEIGHT
for example i want to print: toDAY is a good DAY
having trouble copying multiple needles in stack
i have tried using while (*str) {rest of the function with str++}
i would love some explanation
#define _CRT_SECURE_NO_WARNINGS
#define N 101
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
void replaceSubstring(char* str, char* substr);
void main() {
int flag = 1;
char str[N], substr[N];
//char* str_ptr = &str, * substr_ptr = &substr; //creating pointer for the sake of while
while (flag) {
printf("\nEnter main text: ");
gets_s(str,N);
if (!str)
flag = 0;
printf("\nEnter sub-text: ");
gets_s(substr,N);
if (!str)
flag = 0;
replaceSubstring(str, substr);
printf("%s",str);
}
printf("\nExited. (press any key to exit)");
}
void replaceSubstring(char* str, char* substr) {
int lensbstr;
str = strstr(str, substr);
_strupr(substr); //cnvrt to UPPERCASE
lensbstr = strlen(substr); //length of the mutual string
if (str)
strncpy(str, substr, lensbstr);
}
This looks like a programming exercise, so I’m not going to just give you the answer. However, I’ll give you a few hints.
Two big problems:
You don’t have a loop that would replace the second and later instances.
You are upper-casing the substring... not a copy of the substring. A second pass through replaceSubstring would only match the upper-case version of the substring.
A couple of small problems / style comments:
str is an array, so its value is always non-zero, so “if(!str)” is never true.
strncpy is almost never the right answer. It will work here, but you shouldn’t get in the habit of using it. Its behavior is subtle and is rarely what you want. Here it would be faster and more obvious to use memcpy.
You are upper-casing the substring and measuring its length even if you didn’t find it and so won’t need those results.
Although using int for flags works and is the traditional way, newer versions of the language have stdbool.h, the “bool” type, and the “true” and “false” constants. Using those is almost always better.
You appear to intend to stop when the user enters an empty string for the first string. So why do you ask for the second string in that case? It seems like you want an infinite loop and a “break” in the middle.
I'm making a calc function which is meant to check if the input is valid. So, I'll have 2 strings, one with what the user inputs (eg, 3+2-1 or maybe dog - which will be invalid), and one with the ALLOWED characters stored in a string, eg '123456789/*-+.^' .
I'm not sure how can I do this and have trouble getting it started. I know a few functions such as STRMCP, and the popular ones from the string.h file, but I have no idea how to use them to check every input.
What is the most simplest way to do this?
One way of proceeding is the following.
A string is an array of ascii codes. So if your string is
char formula[50];
then you have a loop
int n =0;
while (formula[n]!=0)
{
if ( (formula[n]<........<<your code here>> ))
{printf("invalid entry\n\n"); return -1; //-1 = error code
n++;
}
you need to put the logic into the loop, but you can test the ascii codes of each character with this loop.
There may be a more elegant way of solving this, but this will work if you put the correct conditional statement here to check the ascii code of each character.
The while statement checks to see ifyou got to the end of the string.
Here's a demonstration of how use strpbrk() to check all characters in a string are in your chosen set:
#include <string.h>
#include <stdio.h>
const char alphabet[] = "123456789/*+-=.^";
int main(void) {
const char a[] = "3+2-1";
const char b[] = "dog";
char *res = strpbrk(a, alphabet);
printf("%s %s\n", a, (res) ? "true" : "false");
res = strpbrk(b, alphabet);
printf("%s %s\n", b, (res) ? "true" : "false");
return 0;
}
That's not the fastest way to do this, but it's very easy to use.
However, if you are writing a calculator function, you really want to parse the string at the same time. A typical strategy would be to have two types of entity - operators (+-/*^) and operands (numbers, so -0.1, .0002, 42, etc). You would extract these from the string as you parse it, and just fail if you hit an invalid character. (If you need to handle parentheses, you'll need a stack for the parsing.... and you'll likely need to work with a stack anyway to process and evaluate the expression overall.)
First time asking a question on here. Apologies if there's already threads about this but i had a few searches and didn't quite find what i think i was looking for. I'm very new to C and am working through a few homework exercises for my microcontroller systems class. We're currently working through easy exercises before we get into embedded C and I'm trying to write a program that'll take a line of text consisting of 10 numbers separated by commas and fill an array of ints with it. As a hint we were told to use a substring and atoi. I think i'm close to getting it right but i can't get it to output my numbers properly.
Also i'm not looking spoon fed answers. A few hints would suffice for now. I'd like to try figuring it out myself before asking for the solution.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int a[10];
char str[] = {1,2,3,4,5,6,7,8,9,10}; //contains string of numbers
int i;
puts("This prints out ten numbers:");
for (i = 0; i < 10; i++)
{
a[i] = atoi(str);
printf("%d", a[i]);
//i'm guessing the problem lies in one of the above two lines
}
return 0;
}
This is outputting the following:
This prints out ten numbers:
0000000000
Thanks to anyone that can help!
Chris
You said that you have to use a line of text separated by commas but you've actually declared a char array containing ten (binary) integers. To get that into a string you just need to do this:
char str[] = "1,2,3,4,5,6,7,8,9,10";
Then you'll need someway to process this string to get each number out and into your array of int.
First off, you should declare a string as follows:
char str[] = {"1,2,3,4,5,6,7,8,9,10"};
the " made the numbers a whole string. Next, you'll need to tokenize them and using the <string.h> library which will come quite handy in this situation.
Here is how you do tokenizing:
define a token buffer first:
char* token;
token = strtok(str,","); //think of it as substring, the part of the str before the comma
for (i = 0; i < 10; i++)
{
a[i] = atoi(token);
printf("%d\t", a[i]);
//i'm guessing the problem lies in one of the above two lines
token = strtok(NULL, ","); //this line is also required for tokenizing the next element
}
Using the strtok() function, you separated the elements between the comas, and got yourself the number strings. Used atoi() function to convert them into integers and printed them. You can see this reference for strtok() function for better understanding.
The problem lies in how you're creating the string.
Please excuse my previous answer, I misunderstood your question:
Simply put, the declaration should be as follows:
char str[] = "1,2,3,4,5,6,7,8,9, 10, 12";
Next, you can use strtok to separate the string into an array of strings omittied the separator (which is in your case the comma), then pass the array members to atoi
Now, why is your code not working?
First, characters should be surrounded by the apostrophes or else the compiler will take the number you pass literally as the ASCII value.
Second, arrays in C like this:
char str[] = {'1', '2', '3', '4', '5'}; don't mean a comma separated string, these commas separate the ARRAY members, each in its own index and not as a whole string.
Your definition of char str[] = {1,2,3,4,5,6,7,8,9,10}; actually sets
the values of the chars to 1 to 10.
In the ASCII-chart of characters, these are unprintable control-characters.
Writing '1' instead of 1 will set the value to the ASCII-value of 1, which is 0x31.
another mistake is that the commas in your definition only seperate the values in the definition, so the result is a array of chars without any seperation, so 12345678910.
so the correct way would be
char str[] = "1,2,3,4,5,6,7,8,9,10";
I've been trying to write a function in C that detects palindromes. The program currently looks like the following:
#include <stdio.h>
#include <string.h>
int main()
{
char palindrome[24]; int palength; int halflength;
gets(palindrome);
palength = strlen(palindrome);
halflength = palength / 2;
printf("That string is %u characters long.\r\n", palength);
printf("Half of that is %u.\r\n", halflength);
return 0;
}
Right now it detects the length of a string, and also shows what half of that is. This is just to make sure it is working how I think it should be. What the rest of the function should do (if possible) is take the integer from "halflength" and use that to take that amount of characters off of the beginning and end of the string and store those in separate strings. From there I'd be able to compare the characters in those, and be able return true or false if the string is indeed a palindrome.
TL;DR - Is it possible take a certain amount of characters (in this case the integer "halflength") off the front and end of a string and store them in separate variables. Read above for more information on what I'm trying to do.
P.S. - I know not to use gets(), but didn't feel like writing a function to truncate \n off of fgets().
int len = strlen(palindrome) - 1; // assuming no \n
int half = len << 1;
for (int i=0; i<=half; ++i)
if(palindrome[i] != palindrome[len-i])
return false;
return true;
What if you do something like this,
char *str1="lol",*str2;
str2=strrev(str1);
//if both are same then it actually is a palindrome ; )
Found out I was approaching the problem wrong. How I should be doing this is iterating over the characters using a pointer both backwards and forwards. Although if you'd still like to answer the original question it could still be useful at some point.
I am learning C and writing a simple program that will take 2 string values assumed to each be binary numbers and perform an arithmetic operation according to user selection:
Add the two values,
Subtract input 2 from input 1, or
Multiply the two values.
My implementation assumes each character in the string is a binary bit, e.g. char bin5 = "0101";, but it seems too naive an approach to parse through the string a character at a time. Ideally, I would want to work with the binary values directly.
What is the most efficient way to do this in C? Is there a better way to treat the input as binary values rather than scanf() and get each bit from the string?
I did some research but I didn't find any approach that was obviously better from the perspective of a beginner. Any suggestions would be appreciated!
Advice:
There's not much that's obviously better than marching through the string a character at a time and making sure the user entered only ones and zeros. Keep in mind that even though you could write a really fast assembly routine if you assume everything is 1 or 0, you don't really want to do that. The user could enter anything, and you'd like to be able to tell them if they screwed up or not.
It's true that this seems mind-bogglingly slow compared to the couple cycles it probably takes to add the actual numbers, but does it really matter if you get your answer in a nanosecond or a millisecond? Humans can only detect 30 milliseconds of latency anyway.
Finally, it already takes far longer to get input from the user and write output to the screen than it does to parse the string or add the numbers, so your algorithm is hardly the bottleneck here. Save your fancy optimizations for things that are actually computationally intensive :-).
What you should focus on here is making the task less manpower-intensive. And, it turns out someone already did that for you.
Solution:
Take a look at the strtol() manpage:
long strtol(const char *nptr, char **endptr, int base);
This will let you convert a string (nptr) in any base to a long. It checks errors, too. Sample usage for converting a binary string:
#include <stdlib.h>
char buf[MAX_BUF];
get_some_input(buf);
char *err;
long number = strtol(buf, &err, 2);
if (*err) {
// bad input: try again?
} else {
// number is now a long converted from a valid binary string.
}
Supplying base 2 tells strtol to convert binary literals.
First out I do recommend that you use stuff like strtol as recommended by tgamblin,
it's better to use things that the lib gives to you instead of creating the wheel over and over again.
But since you are learning C I did a little version without strtol,
it's neither fast or safe but I did play a little with the bit manipulation as a example.
int main()
{
unsigned int data = 0;
int i = 0;
char str[] = "1001";
char* pos;
pos = &str[strlen(str)-1];
while(*pos == '0' || *pos == '1')
{
(*pos) -= '0';
data += (*pos) << i;
i++;
pos--;
}
printf("data %d\n", data);
return 0;
}
In order to get the best performance, you need to distinguish between trusted and untrusted input to your functions.
For example, a function like getBinNum() which accepts input from the user should be checked for valid characters and compressed to remove leading zeroes. First, we'll show a general purpose in-place compression function:
// General purpose compression removes leading zeroes.
void compBinNum (char *num) {
char *src, *dst;
// Find first non-'0' and move chars if there are leading '0' chars.
for (src = dst = num; *src == '0'; src++);
if (src != dst) {
while (*src != '\0')
*dst++ = *src++;
*dst = '\0';
}
// Make zero if we removed the last zero.
if (*num == '\0')
strcpy (num, "0");
}
Then provide a checker function that returns either the passed in value, or NULL if it was invalid:
// Check untested number, return NULL if bad.
char *checkBinNum (char *num) {
char *ptr;
// Check for valid number.
for (ptr = num; *ptr == '0'; ptr++)
if ((*ptr != '1') && (*ptr != '0'))
return NULL;
return num;
}
Then the input function itself:
#define MAXBIN 256
// Get number from (untrusted) user, return NULL if bad.
char *getBinNum (char *prompt) {
char *num, *ptr;
// Allocate space for the number.
if ((num = malloc (MAXBIN)) == NULL)
return NULL;
// Get the number from the user.
printf ("%s: ", prompt);
if (fgets (num, MAXBIN, stdin) == NULL) {
free (num);
return NULL;
}
// Remove newline if there.
if (num[strlen (num) - 1] == '\n')
num[strlen (num) - 1] = '\0';
// Check for valid number then compress.
if (checkBinNum (num) == NULL) {
free (num);
return NULL;
}
compBinNum (num);
return num;
}
Other functions to add or multiply should be written to assume the input is already valid since it will have been created by one of the functions in this library. I won't provide the code for them since it's not relevant to the question:
char *addBinNum (char *num1, char *num2) {...}
char *mulBinNum (char *num1, char *num2) {...}
If the user chooses to source their data from somewhere other than getBinNum(), you could allow them to call checkBinNum() to validate it.
If you were really paranoid, you could check every number passed in to your routines and act accordingly (return NULL), but that would require relatively expensive checks that aren't necessary.
Wouldn't it be easier to parse the strings into integers, and then perform your maths on the integers?
I'm assuming this is a school assignment, but i'm upvoting you because you appear to be giving it a good effort.
Assuming that a string is a binary number simply because it consists only of digits from the set {0,1} is dangerous. For example, when your input is "11", the user may have meant eleven in decimal, not three in binary. It is this kind of carelessness that gives rise to horrible bugs. Your input is ambiguously incomplete and you should really request that the user specifies the base too.