I'm looking for converting each ordinal value returned from web_reg using web_convert_param in for loop and do some operations. Below is my code:
char str1[] = "";
web_reg_save_param("fetch", "LB=XXXXX", "RB=YYYYY", "ORD=ALL", LAST);
lr_param_sprintf("c_final_buf", "");
for (k = 1; k <= atoi(lr_eval_string("{fetch_count}")); k++){
sprintf(str1, "%s", lr_paramarr_idx("fetch",k));
lr_save_string(str1, "buffer1");
web_convert_param("buffer1Conv", "SourceString={buffer1}", "SourceEncoding=PLAIN", "TargetEncoding=URL",LAST);
lr_param_sprintf("c_buffer", "ABC%s=%s&",
lr_paramarr_idx("c_param",k), lr_eval_string("{CovPunchVal}"));
lr_param_sprintf("c_final_buf", "%s%s", lr_eval_string("{c_final_buf}"), lr_eval_string("{c_buffer}"));
}
By using above code sometime's I am getting MEMORY VIOLATION EXCEPTION at sprintf(str1, "%s", lr_paramarr_idx("fetch",k));. Can someone please suggest how can I achieve above without involving any external variables.
EDIT1: Would like to avoid using lr_paramarr_idx("c_param",k) as well as it may cause memory exceptions during run times as per few online forms.
The reason you are getting MEMORY VIOLATION EXCEPTION at sprintf(str1, "%s", lr_paramarr_idx("fetch",k)); may be related to str1 declaration.
It should be fixed size character array like char str1[256]; rather than char str1[] = "";
Also, maybe the follwing code may be of use to you as an alternative:
int k;
int count;
//web_reg_save_param("fetch", "LB=XXXXX", "RB=YYYYY", "ORD=ALL", LAST);
// simulation of parameters array
lr_save_string("101:abc","fetch_1");
lr_save_string("102:abc","fetch_2");
lr_save_string("103:abc","fetch_3");
lr_save_string("104:abc","fetch_4");
lr_save_string("105:abc","fetch_5");
lr_save_string("106:abc","fetch_6");
lr_save_string("107:abc","fetch_7");
lr_save_string("108:abc","fetch_8");
lr_save_string("109:abc","fetch_9");
lr_save_string("110:abc","fetch_10");
lr_save_string("111:abc","fetch_11");
lr_save_string("112:abc","fetch_12");
lr_save_string("113:abc","fetch_13");
lr_save_string("114:abc","fetch_14");
lr_save_string("115:abc","fetch_15");
lr_save_string("116:abc","fetch_16");
lr_save_string("117:abc","fetch_17");
lr_save_string("118:abc","fetch_18");
lr_save_string("119:abc","fetch_19");
lr_save_string("120:abc","fetch_20");
lr_save_string("20","fetch_count");
// convert values inside array
count = atoi(lr_eval_string("{fetch_count}"));
for (k = 1; k <= count; k++){
lr_save_int(k,"ParamIndex");
web_convert_param(lr_eval_string("fetch_{ParamIndex}"), "SourceEncoding=PLAIN", "TargetEncoding=URL",LAST);
}
// continue the required manipulations…
Issue got resolved now. Below is the update code:
char tmpbuf[256];
for (k = 1; k <= atoi(lr_eval_string("{fetch_count}")); k++){
// sprintf(str1, "%s", lr_paramarr_idx("fetch",k));
// lr_save_string(str1, "buffer1");
sprintf(tmpbuf, lr_paramarr_idx("fetch",k));
lr_save_string(tmpbuf, "buffer1");
web_convert_param("buffer1Conv", "SourceString={buffer1}", "SourceEncoding=PLAIN", "TargetEncoding=URL",LAST);
lr_param_sprintf("c_buffer", "ABC%s=%s&",
lr_paramarr_idx("c_param",k), lr_eval_string("{CovPunchVal}"));
lr_param_sprintf("c_final_buf", "%s%s", lr_eval_string("{c_final_buf}"), lr_eval_string("{c_buffer}"));
}
Related
trying to copy stuff from b into a but i get that error
someone told me it means i'm trying to access memory that i'm not allowed to, but i don't know what should i do to make it compile.
replace(txt , code);
string replace(string a , string b)
{
string alpha[26] = {"abcdefghijklmnopqurstuvwxyz"};
for (int i = 0; i < strlen(a); i++)
{
for(int n = 0; n < 26; n++)
{
if(a[i] == alpha[n])
{
a[i] = b[n];
i++;
}
}
}
return word;
}
i'm a beginner so no comments about clean coding or syntactic sugar or stuff like that just help me resolve this please
It looks like you have some problems with understending pointers, so I recommend you to read about them. Also consider reading about datatypes and types from STL you are using. (cause std::string is already an array of values so, when you are creating std::string[26], you actually are creating pointer to a pointer)
I guess you have are trying to do something like that:
std::string replace(string a , string b)
{
std::string alpha = {"abcdefghijklmnopqurstuvwxyz"};
for (size_t i = 0; i < a.size(); ++i)
{
for(size_t n = 0; n < alpha.size(); ++n)
{
if(a[i] == alpha[n])
{
a[i] = b[n];
i++; // Also, I think you doesnt need this line, cause you already incrementing i in for loop
}
}
}
return a;
}
Also you have used strlen() on your string, that also is not really correct, cause it is used on char values. If you whant to get length of a string it is better to use string.lenght()
Also, It is better to use size_t or unsigned int instead of int in this case, cause you don't need negative numbers in order to parce these strings. ()
Consider this simple program that concatenates all specified parameters and prints them in standard output. I used 2 for loops to append the strings, one to calculate the length of that string and one to concatenate the strings. Is there a way doing it with only one loop? It wouldn't be more efficient reallocating memory for each string to concatenate, would it? How would Java's StringBuilder be implemented in C? Would it loop twice as I did?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
size_t len = 0;
// start for loop at i = 1 to skip the program name specified in argv
for(int i = 1; i < argc; i++)
len += strlen(argv[i]) + 1; // +1 for the space
char* toAppend = (char*)malloc(len * sizeof(char) + 1);
toAppend[0] = '\0'; // first string is empty and null terminated
for(int i = 1; i < argc; i++)
{
strcat(toAppend, argv[i]);
strcat(toAppend, " ");
}
printf(toAppend);
free(toAppend);
}
Your method of allocation is efficient, measuring the total length and allocating just once. But the concatenation loop repeatedly measures the length of the output buffer from the start to concatenate to it, resulting in quadratic runtime.
To fix it track your position as you go:
size_t pos = 0;
for(int i = 1; i < argc; i++) {
size_t len = strlen(argv[i]);
memcpy(toAppend+pos, argv[i], len);
pos += len;
toAppend[pos] = ' ';
pos++;
}
toAppend[pos] = 0;
This is the most efficient way to actually concatenate in memory, but the most efficient of all is not to concatenate. Instead:
for(int i = 1; i < argc; i++)
printf("%s ", argv[i]);
The whole reason stdio is buffered is so you don't have to build arbitrary-length in-memory buffers to do efficient output; instead it buffers up to a fixed size automatically and flushes when the buffer is full.
Note that your usage of printf is wrong and dangerous in the event that your input contains a % character anywhere; it should be printf("%s", toAppend);.
If you're writing to POSIX (or POSIX-ish) systems rather than just plain C, another option would be fmemopen, which would allow you to write the loop just as:
for(int i = 1; i < argc; i++)
fprintf(my_memfile, "%s ", argv[i]);
efficient way to concatenate strings in c
An efficient way is to calculate the string lengths - and remember them.
size_t sum = 1; // for \0
if (argc > 2) sum += argc - 2. // spaces
size_t length[argc]; // This is a VLA, available C99 and optionally in C11
for(int i = 1; i < argc; i++)
length[i] = strlen(argv[i]);
sum += length[i];
}
Then allocate, and then check for errors.
char *dest = malloc(sum);
if (dest == NULL) Handle_OutOfMemory();
Copy each string in turn
char *p = dest;
for(int i = 1; i < argc; i++)
// Use either memcpy() or strcpy().
// memcpy() tends to be faster for long strings than strcpy().
memcpy(p, argv[i], length[i]);
p += length[i]; // advance insertion point
if (i > 1) {
*p++ = ' '; // space separators
}
}
*p = '\0';
Now use dest[].
printf("<%s>\n", dest);
Free resources when done.
free(dest);
It wouldn't be more efficient reallocating memory for each string to concatenate, would it?
Usually repetitive re-allocations is best avoided, yet for small short strings it really makes scant difference. Focus on big O. My answer is O(n). Relocating in a loop tends to be O(n*n).
If performance was critical, try various approaches and profile for the intended system. The point being what is fast on one machine may differ on another. Usually it is best to first code a reasonable clear approach.
The most efficient way is probably to not use any str functions and copy the characters "by hand":
char* toAppend = malloc(len + 1);
size_t j = 0;
for(size_t i = 1; i < argc; i++)
{
for(size_t k = 0; argv[i][k]; k++)
toAppend[j++] = argv[i][k];
toAppend[j++] = ' ';
}
toAppend[j - 1] = '\0'; // Remove the last space and NULL-terminate the string
helloeveryone. I am fairly new to programming and currently trying to learn C programming to advance further in any of my projects. I've just learned how to use malloc and realloc, and all seemed good until I attempted to use strcat to combine two given strings from multidimensional array.
I am supposed to get combination of two strings based on the user inputs, and strangely, the first character is either missing or replaced by other characters...
I'll include the source code as well as the output below. I'd really appreciate you help. Thanks in advance!! ( don't mind the Korean at the end... I am korean :P)
enter code here
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
int i, j;
const int row = 3;
char *pstr[3];
char temp[100];
int k,p = 0;
printf("Type in any three characters\n");
for (i = 0; i < row; i++)
{
pstr[i] = (char *)malloc(strlen(temp) + 1); //initialize the lenght of the elements in 2 part of 2D array of char b[ROW] via length of the given string
}
for (i = 0; i < row; i++)
{
scanf("%s", temp);
strcpy(pstr[i], temp);
}
printf("\n");
for (i = 0; i < row; i++)
{
printf("%s\n", pstr[i]);
}
scanf("%d", &p);
scanf("%d", &k);
printf("%s\n", pstr[p]);
printf("%s\n", pstr[k]);
*pstr[k] = (char *)realloc(pstr[k], strlen(pstr[p])+100);
strcat(pstr[k], pstr[p]);
printf("%s", pstr[k]);
for (i = 0; i < row; i++)
{
free(pstr[i]);
}
return 0;
}
\
output::LINK IS AN INTERNATIONAL SIGN FOR , IMAGE OVER HERE!!!
Two major problems:
You use temp before it have been initialized, when its contents is indeterminate and that will lead to undefined behavior.
When you do *pstr[k] = realloc(...) you dereference the pointer in pstr[k] and gets it's first element, which is a single character. You then assign the result of the realloc call to this char element. So you basically lose the actual pointer and pstr[k] will still point to the same memory (which might now be invalid).
There are other problems, but these two are the worst.
I found these in your code
1) if k or p is greater than 2 it will give runtime error
2) *pstr[k] = (char *)realloc(pstr[k], strlen(pstr[p])+100);
but this line can give error in compile time also(mac at least) - as they are not same
so you may change like this -
*pstr[k] = *(char *)realloc(pstr[k], strlen(pstr[p])+100);
3) After realloc you will get exception in free. see this - How free memory after of realloc
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am writing a program in C that replaces a number in a char* called "template" with a string, but I continually get a Segmentation Fault: 11 error.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
char *rep_str(const char *s, const char *old, const char *new1){
char *ret;
int i, count = 0;
int newlen = strlen(new1);
int oldlen = strlen(old);
for (i = 0; s[i] != '\0'; i++){
if (strstr(&s[i], old) == &s[i]){
count++;
i += oldlen - 1;
}
}
ret = (char*)malloc(i + count * (newlen - oldlen));
if (ret == NULL)
exit(EXIT_FAILURE);
i = 0;
while (*s){
if (strstr(s, old) == s){ //compare the substring with the newstring
strcpy(&ret[i], new1);
i += newlen; //adding newlength to the new string
s += oldlen;//adding the same old length the old string
} else {
ret[i++] = *s++;
}
}
ret[i] = '\0';
return ret;
}
char* madlib_by_numbers(char* temp, int word_count, char* words[]){
char* numbers[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
int tempSize = strlen(temp);
for (int i = 0; i < tempSize; i++){
if (isdigit(temp[i])){
for (int j = 0; j < (sizeof(numbers) / sizeof(char*)); j++){
temp = rep_str(temp, numbers[j], words[j]); //it makes it to this line, but never gets to assert()
}
}
}
return temp;
}
int main() {
char* temp1 = "The 1 0 likes to 2 in the moonlight.";
char* words[] = {"git", "brilliant", "swim"};
char* result = "The brilliant git likes to swim in the moonlight.";
int stringLength = strlen(result);
char* test = madlib_by_numbers(temp1, 3, words);
assert(strncmp(test, result, stringLength) == 0);
free(test);
return 0;
}
and when I run the debugger, it simply says: Segmentation Fault: 11
What i just want to understand is where the segmentation fault error is coming from, I have the suspicion one of my loops is running too many times.
There are a few issue with your code. However, the direct answer to your question is in this loop:
for (int j = 0; j < (sizeof(numbers) / sizeof(char*)); j++){
temp = rep_str(temp, numbers[j], words[j]);
}
You are calling rep_str for every digit while you mean call rep_str only if the digit in temp matches the corresponding digit in numbers. So add this conditional if(strcmp(temp,numbers[j]) == 0) right before the line temp=.... Then it'll solve your current problem.
The segfault is caused because there are only three elements in the words array. Your old loop indexes from 0 to 9 and fails when j=3, out of bound.
Also, delete the free() at the end of your program. test was never allocated and will cause a core dump.
ret = (char*)malloc(i + count * (newlen - oldlen));
There are a few problems with this line of code.
For a start, don't cast malloc (or any void * that you're assigning to a variable of different pointer type, or vice versa).
If you intended to allocate space to store a string, where's the string-terminating '\0' going to go? You need to realise that for an empty old string, this will be malloc(0) and zero bytes is not enough to store an empty string.
There's also a problem if you expect that old may be a substring of new (for example, you're replacing "0" with "hell0"). You'll need to tweak your algorithm to handle this problem. I'll leave that as a challenge for you to attempt :)
for (int i = 0; i < tempSize; i++){
if (isdigit(temp[i])){
for (int j = 0; j < (sizeof(numbers) / sizeof(char*)); j++){
temp = rep_str(temp, numbers[j], words[j]); //it makes it to this line, but never gets to assert()
}
}
}
users previous answer highlighted this code correctly, but not for the right reason... and so the solution he/she presented is wrong.
isdigit(temp[i]) may also cause segfaults for some inputs. I recommend using isdigit((unsigned char) temp[i]) instead, in this case.
It's not valid to access words[j] where word_count is 3 and j is greater or equal to 3; you're accessing that array out of bounds.
You also need to be careful to free any memory you *alloc (while simultaneously not freeing memory that you don't *alloc). Forgetting to do the former won't cause crashes, but your program won't run happily; it'll use heaps of memory.
Consider something like this, instead:
temp = strdup(temp);
if (temp == NULL) {
exit(EXIT_FAILURE);
}
for (int i = 0; i < tempSize; i++){
if (isdigit((unsigned char) temp[i])){
for (int i = min(word_count, sizeof(numbers) / sizeof(char*)), j = 0; j < i; j++){
char *new = rep_str(temp, numbers[j], words[j]);
free(temp);
temp = new;
}
}
}
I am writing this exercise of bubble sort and I have to create 2 source files. The first contains the main code and the second contains my bubble sort algorithm. The main code includes the bubblesort.
Main:
#include<stdio.h>
#include<string.h>
#include"2.c"
int main(void)
{
char text[100];
int length;
printf("Insert text: \n");
gets(text);
text=bsort(text);
printf("String : %s \n",text);
return 0;
}
Bubblesort:
char *bsort(char text[100]){
char temp[100];
int length,i,j;
length=strlen(text);
for(i=1;i<length;i++){
for(j=0;j<length-i;j++){
if(text[j]>text[j+1]){
temp[0]=text_input[j]; //
text_input[j]=text_input[j+1];//Edit,had wrong code posted
text_input[j+1] =temp[0]; //
}
}
}
return text;}
The thing is ,when i run it, i get a " incompatible types when assigning to type 'char[100]' from type 'char *'" error
I'm terribly new to c and I'm kinda lost, I'm browsing for an answer for quite some hours now. I understand that the function will return a char instead of char array(known as a string from java experience), but I just can't get to find a way to do this as hard as I try.
A solution would be great or just a small help would be appreciated.
EDIT: I forgot to mention what my program actually does. It is supposed to get a string from the user, apply the bubblesort algorithm which is is going to sort every character in the string alphabetically, i.e. "bagf" will be output as "abfg". Also added some comments
First please write your code in a way that it's readable, your problem is that you are not swapping any values
char *bsort(char text[100])
{
char temp[100];
int length, i, j;
length = strlen(text);
for(i = 1 ; i < length ; i++)
{
for (j = 0 ; j < length - i ; j++)
{
if(text[j] > text[j + 1])
{
temp[0] = text[j];
text[j] = text[j+1];
text[j + 1] = temp[0];
}
}
}
return text;
}