0

I am having a problem whereby the letter at the position(e.g 39) would be replaced with the text I wanted to input. However what I want was to insert the text at position 39 instead of replacing it. Anyone please guide me on this.

string description = variables[1]["value"].ToString();// where I get the text
int nInterval = 39;// for every 39 characters in the text I would have a newline
string res = String.Concat(description.Select((c, z) => z > 0 && (z % nInterval) == 0 ? Environment.NewLine +"Hello"+(((z/ nInterval)*18)+83).ToString()+"world": c.ToString()));
file_lines = file_lines.Replace("<<<terms_conditions>>>",resterms); //file_lines is where I read the text file 

Original text

Present this redemption slip to receive: One

After String.Concat

Present this redemption slip to receive\r\n\u001bHello101world
One //: is gone 

I am also having a issue where I want to put a new line if it contains * in the text. If anybody is able to help that would be great.

Edit: What I want to achieve is something like this

Input

*Item is considered paid if unsealed.*No replacement or compensation will be given for any expired coupons.

so like i need to find every 39 character and also * to input newline so it will be

Output

*Item is considered paid if unsealed.  
*No replacement or compensation will be  
given for any expired coupons.
tbx1
  • 11
  • 3
  • 4
    I would personally just use `string.Insert` for this rather than doing it all with LINQ. The code you've got at the moment is hard to understand (for me, anyway) whereas I'd expect code using `string.Insert` to be pretty simple. – Jon Skeet Dec 03 '18 at 07:53
  • In addition to Jon Skeet's comment, you can read [String.Insert specs here](https://learn.microsoft.com/fr-fr/dotnet/api/system.string.insert?view=netframework-4.7.2) – Rafalon Dec 03 '18 at 07:55

3 Answers3

0

Try String.Insert(Int32, String) Method

Insert \n where you need new line.

SᴇM
  • 7,024
  • 3
  • 24
  • 41
gkumar
  • 1
  • 2
  • No, one should use `Environment.NewLine`. Usually just `\n` is wrong for Windows platforms. – ckuri Dec 03 '18 at 08:14
0

If I understood your question properly, you want a newline after every 39 characters. You can use string.Insert(Int32, String) method for that.

And use String.Replace(String, String) for your * problem.

Below code snippet doing that using a simple for loop.

        string sampleStr = "Lorem Ipsum* is simply..";

        for (int i = 39;  i < sampleStr.Length;  i = i + 39){
            sampleStr = sampleStr.Insert(i, Environment.NewLine);
        }

        //sampleStr = sampleStr.Replace("*", Environment.NewLine);

        int[] indexes = Enumerable.Range(0, sampleStr.Length).Where(x => sampleStr[x] == '*').ToArray();

        for (int i = 0; i < indexes.Length; i++)
        {
            int position = indexes[i];
            if (position > 0) sampleStr = sampleStr.Insert(position, Environment.NewLine);
        }

If you want to do both together

        int[] indexes = Enumerable.Range(0, sampleStr.Length).Where(x => sampleStr[x] == '*' || x % 39 == 0).ToArray();
        int j = 0;

        foreach (var position in indexes)
        {
            if (position > 0)
            {
                sampleStr = sampleStr.Insert(position + j, Environment.NewLine);
                j = j + 2; // increment by two since newline will take two chars 
            }
        }
cdev
  • 5,043
  • 2
  • 33
  • 32
  • Alternatives: https://stackoverflow.com/questions/7768373/c-sharp-line-break-every-n-characters – cdev Dec 03 '18 at 08:24
  • Hi thanks for your reply. After inserting newline, I am currently stuck with adding (((z/ nInterval)*18)+83) as I have another variable n where it needs to increase in order to move the text down – tbx1 Dec 03 '18 at 10:09
  • Correct me if I am wrong, so if we are using for loop , I will first use the loop to insert every 39 characters with e.g (#). Then I will use another loop to get the each index of # to replace with this function `"Hello"+(((z/ nInterval)*18)+83).ToString()+"world"` where z will keep changing as z is the positions/index of #. //This is the part that I've been cracking my head but still got no idea how to procees currently – tbx1 Dec 03 '18 at 10:20
  • Sorry I cant understand properly your requirement, can you please provide example of input string and expected output string. – cdev Dec 04 '18 at 02:06
  • Hi I've made an edit on my post, do take a look. Thanks for your help :) – tbx1 Dec 04 '18 at 03:28
  • Update the answer, please check now. – cdev Dec 04 '18 at 05:05
0

Without debating the method chosen to achieve the desired result, the problem with the code is that at the 39th character it adds some text, but the character itself has been forgotten.

Changing the following line should give the expected output.

string res = String.Concat(description.Select((c, z) => z > 0 && (z % nInterval) == 0 ? Environment.NewLine + "Hello" + (((z / nInterval) * 18) + 83).ToString() + "world" + c.ToString() : c.ToString()));

<== UPDATED ANSWER BASED ON CLARIFICATION IN QUESTION ==>

This will do what you want, I believe. See comments in line.

        var description = "*Item is considered paid if unsealed.*No replacement or compensation will be given for any expired coupons.";

        var nInterval = 39; // for every 39 characters in the text I would have a newline
        var newline = "\r\n"; // for clarity in the Linq statement.  Can be set to Environment.Newline if desired.
        var z = 0; // we'll handle the count manually.

        var res = string.Concat(
            description.Select(
                (c) => (++z == nInterval || c == '*') // increment z and check if we've hit the boundary OR if we've hit a *
                    && ((z = 0)==0) // resetting the count - this only happens if the first condition was true 
                    ? newline + (c == ' ' ? string.Empty : c.ToString()) // if the first character of a newline is a space, we don't need it
                    : c.ToString()
                ));

Output:

*Item is considered paid if unsealed.
*No replacement or compensation will be
given for any expired coupons.
Brett
  • 1,540
  • 9
  • 13
  • Yup that's what I wanted to achieve for the first half , but I am having problems including the condition where it also adds a newline for ("*"). Under some circumstances , Environment.NewLine doesn't work for my case hence I have to use the calculation I have made to make the text move down(aka newline). Appreciate your help anyways:) – tbx1 Dec 04 '18 at 03:31
  • Thanks for the clarification in your question with respect to behavior with `*` character. I have updated my answer. – Brett Dec 04 '18 at 10:13
  • Hi i've tried your answer, it works in a way but it doesn't help me with the next line part as the increments becomes 0 , which I needed it for this function to work `(((z / nInterval) * 18) + 83).ToString()` to move the text down – tbx1 Dec 05 '18 at 03:29
  • I confess, I don't understand why you need to add a number to the output to effect a new line. However, you just need to add a declaration `var newlineCount = 0` and increment it when it is referenced `... + ((++newlineCount * 18)+83).ToString() + ...`. – Brett Dec 05 '18 at 08:40