how to copy env without leaks - linked-list

Another Example For copy
But it makes segmentation faults
typedef struct s_env
{
char *key;
char *val;
struct s_env *next;
} t_env;
void env_tokenizing(char **envp, t_env **env)
{
int i;
char **_tok;
i = -1;
*env = malloc(sizeof(t_env));
if(!env)
return ;
while(envp[++i])
{
_tok = ft_split(envp[i], '=');
(*env)->key = _tok[0];
(*env)->val = _tok[1];
if (!envp[i + 1])
break;
(*env)->next = malloc(sizeof(t_env));
if(!(*env)->next)
return ;
env = &(*env)->next;
}
(*env)->next = NULL;
}
void env_tokenizing(char **envp, t_env **env)
{
int i;
char **_tok;
i = -1;
*env = malloc(sizeof(t_env));
if(!env)
return ;
while(envp[++i])
{
_tok = ft_split(envp[i], '=');
keyval((*env)->key, _tok[0]);
keyval((*env)->val, _tok[1]);
if (!envp[i + 1])
break;
(*env)->next = malloc(sizeof(t_env));
if(!(*env)->next)
return ;
env = &(*env)->next;
}
(*env)->next = NULL;
}
void keyval(char *locate, char *kv)
{
int i;
size_t len;
len = ft_strlen(kv);
locate = malloc(sizeof(char) * (len + 1));
if(!locate)
return ;
i = -1;
while(kv[++i])
locate[i] = kv[i];
locate[i] = '\0';
free(kv);
}
I'm going to copy environment variables from **envp argument from main without leaks. When I try to split every line in envp with = sign with [0] index i put the value to my env->key member, and a value of index [1] put to env->val member. But it leaves leaks behind. How can I add nodes to my env linked list withg key value members with **envp values. Here are two examples how I copied values.
In second example copy with keyval() function programm makes segmentation faluts.

Related

Cs50 speller: not recognising any incorrect words

I'm currently working on the CS50 Speller function. I have managed to compile my code and have finished a prototype of the full program, however it does not work (it doesn't recognise any mispelled words). I am looking through my functions one at a time and printing out their output to have a look at what's going on inside.
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
char word[LENGTH + 1];
int counter = 0;
FILE *dicptr = fopen(dictionary, "r");
if (dicptr == NULL)
{
printf("Could not open file\n");
return 1;
}
while (fscanf(dicptr, "%s", word) != EOF)
{
printf("%s", word);
node *n = malloc(sizeof(node));
if (n == NULL)
{
unload();
printf("Memory Error\n");
return false;
}
strcpy(n->word, word);
int h = hash(n->word);
n->next = table[h];
table[h] = n;
amount++;
}
fclose(dicptr);
return true;
}
From what I can see this works fine. Which makes me wonder if the issue is with my check function as shown here:
bool check(const char *word)
{
int n = strlen(word);
char copy[n + 1];
copy[n] = '\0';
for(int i = 0; i < n; i++)
{
copy[i] = tolower(word[i]);
printf("%c", copy[i]);
}
printf("\n");
node *cursor = table[hash(copy)];
while(cursor != NULL)
{
if(strcasecmp(cursor->word, word))
{
return true;
}
cursor = cursor->next;
}
return false;
}
If someone with a keener eye can spy what is the issue I'd be very grateful as I'm stumped. The first function is used to load a the words from a dictionary into a hash table\linked list. The second function is supposed to check the words of a txt file to see if they match with any of the terms in the linked list. If not then they should be counted as incorrect.
This if(strcasecmp(cursor->word, word)) is a problem. From man strcasecmp:
Return Value
The strcasecmp() and strncasecmp() functions return an
integer less than, equal to, or greater than zero if s1 (or the first
n bytes thereof) is found, respectively, to be less than, to match, or
be greater than s2.
If the words match, it returns 0, which evaluates to false.

Add char in between string

I want a function which takes string as an argument and add any char between string after every 3 letters.
For example:
func("11111111"){}
will return:
11,111,111
If I understand your question correctly
import 'dart:math' as math;
String convertFun(String src, String divider) {
String newStr = '';
int step = 3;
for (int i = 0; i < src.length; i += step) {
newStr += src.substring(i, math.min(i + step, src.length));
if (i + step < src.length) newStr += divider;
}
return newStr;
}
UPD:
(for separating symbols from end, not from beginning)
String convertFun(String src, String divider) {
String newStr = '';
int step = 3;
for (int i = src.length - 1; i >= 0; i -= step) {
String subString ='';
if (i > 3) {
subString += divider;
}
subString += src.substring( i < step ? 0 : i - step, i);
newStr = subString + newStr;
}
return newStr;
}
String func(String str){
RegExp exp = RegExp(r".{1,3}");
Iterable<Match> matches = exp.allMatches(str);
List<dynamic> list = [];
matches.forEach((m)=>list.add(m.group(0)));
return list.join(',');
}
Try this:
String myFunction(String str, String separator) {
String tempString = "";
for(int i = 0; i < str.length; i++) {
if(i % 3 == 0 && i > 0) {
tempString = tempString + separator;
}
tempString = tempString + str[i];
}
return tempString;
}
And use it for example, like this:
Text(myFunction("111111111", ","))
The other solutions work for your stated problem, but if you are looking to add commas in numbers (as in your example), you'll want to add the comma's from the right to the left instead.
ie: 12345678 you would want 12,345,678 not 123,456,78
String convertFun(String src, String divider) {
StringBuilder newStr = new StringBuilder();
int step = 3;
for (int i = src.length(); i > 0; i -= step) {
newStr.insert(0, src.substring( i < step ? 0 : i - step, i));
if (i > 3) {
newStr.insert(0, divider);
}
}
return newStr.toString();
}

Swap 2 nodes of a single linked list. i have the program. I need to ask where its wrong

I wrote the following program. The swap is working fine if i debug it. However i am not able to return the complete linked list. It is changing the head as well. what is wrong?
public static Node<Integer> swapElementsAtiAndj(Node<Integer> head, int i, int j)
{
Node<Integer> temp= head;
Node<Integer> prev1 = temp;
Node<Integer> prev2 = temp;
Node<Integer> toSwap1 = temp;
Node<Integer> toSwap2 = temp;
int count =0;
int pos1 =i;
int pos2 =j;
if(i>j) {
pos1 = j;
pos2 =i;
}
while (count !=pos1) {
prev1 = toSwap1;
toSwap1 = toSwap1.next;
prev2 = prev1;
toSwap2 = toSwap1;
count++;
}
while(count != pos2) {
prev2 = toSwap2;
toSwap2 = toSwap2.next;
count++;
}
temp.data = toSwap1.data;
temp.next = toSwap2.next;
toSwap2.next = toSwap1.next;
prev2.next = temp;
prev1.next = toSwap2;
return head;
}
Yes, your head is getting modified at
temp.next = toSwap2.next;
Because temp is pointing at head. Here is how you can fix it:
First of all,
prev2 = prev1;
toSwap2 = toSwap1;
can be written outside of while loop.
Now, after second while loop toSwap1 and toSwap2 are pointing at elements to be swapped.
// Swap prev
prev1.next = toSwap2;
prev2.next = toSwap1;
// Store toSwap2's next in temp
temp = toSwap2.next;
// Set toSwap2's next to toSwap1's next
toSwap2.next = toSwap1.next;
// Set toSwap1's next to old toSwap2's next (i.e temp)
toSwap1.next = temp;
// Return
return head;

Groovy string match 90% (ignore letter casing)

I need to write a Groovy function to check if two given strings match at least 90%. I just wanted to know if anyone knew of an already existent such utility method that I could use in a Grails project. I haven't really written the method yet but ideally this is how it would work:
def doStringsMatch(String str1, String str2) {
if (str1 and str2 match at least 90% or
str1 appears in str2 somewhere or
str2 appears in str1 somewhere)
return true
else
return false
}
Thanks
This is a groovy implementation of Levenshtein distance, basically it returns a percentage of how similar the two strings appear to be. 0 means they are completely different and 1 means they are the exact same. This implementation is case insensitive.
private double similarity(String s1, String s2) {
if (s1.length() < s2.length()) { // s1 should always be bigger
String swap = s1; s1 = s2; s2 = swap;
}
int bigLen = s1.length();
if (bigLen == 0) { return 1.0; /* both strings are zero length */ }
return (bigLen - computeEditDistance(s1, s2)) / (double) bigLen;
}
private int computeEditDistance(String s1, String s2) {
s1 = s1.toLowerCase();
s2 = s2.toLowerCase();
int[] costs = new int[s2.length() + 1];
for (int i = 0; i <= s1.length(); i++) {
int lastValue = i;
for (int j = 0; j <= s2.length(); j++) {
if (i == 0)
costs[j] = j;
else {
if (j > 0) {
int newValue = costs[j - 1];
if (s1.charAt(i - 1) != s2.charAt(j - 1))
newValue = Math.min(Math.min(newValue, lastValue),
costs[j]) + 1;
costs[j - 1] = lastValue;
lastValue = newValue;
}
}
}
if (i > 0)
costs[s2.length()] = lastValue;
}
return costs[s2.length()];
}

How to fix the row value mapping Index was out of range. Must be non-negative and less than the size of the collection c#

I am getting the error out of range object[,]
string MissingCompanies="";
List<string> cmp = new List<string>();
cmp = sr.CompanyCode();
int count=0;
if (DataRange!=null)
{
while (DataRange != null)
{
string code;
bool match;
match = false;
code = cmp[count]; //getting error here**
for (int dr = 1; dr <= DataRange.GetUpperBound(0); dr++)
{
if (code.Equals(DataRange[dr, 1]))
{
match = true;
break;
}
}
count++;
if (!match)
{
MissingCompanies = MissingCompanies + "," + code;
}
I'm getting error: code=cmp[count] -- index has out of range.
I'd be grateful for any help with this.

Resources