Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have implemented a method that requires 2 parameters (arguments) : the first one is the source of the xml file ( type string) and the second one is the destination path of the generated pdf file (type string)
This application will be used by another application that will assign automatically the 2 parameters.
My question is how should I declare the 2 arguments until I can assign external parameters?
in other meaning : I implemented a console appication . When calling it from cmd , it looks like that : C:> name_of_apllication "path1" "path2". How should I implement the parameters if the called method until they will replaced by "path1" and "path2"?
this is the code of the main class : the method that will be used is : GeneratePDF_CTAF
static void Main(string[] args)
{
string input = "";
string output = "";
GeneratePDF.GeneratePDF_Ctaf( ref input, ref output );
}
this is the error screen , it is in french and that means can not find file
The command line arguments are passed to the Main method as an array of strings. This is the args parameter in your code, so you can simply extract the parameters you need from there:
static int Main(string[] args)
{
if (args.Length != 2)
{
Console.Error.WriteLine("This program requires exactly 2 parameters");
return 1; // error code
}
string input = args[0];
string output = args[1];
GeneratePDF.GeneratePDF_Ctaf(input, output);
return 0; // no error
}
Note here, I've modified Main to return an int. A non-zero return value is often used in console applications to provide error information to the calling program. I've also removed the ref keyword from your parameters because it's almost never necessary to use ref parameters in .NET.
I think there is something fundamental about using a function that you are not understanding so I will give a short example -- if it does not solve your problem please explain why not:
void Main(string[] args)
{
aFunction(args[1], args[2]);
}
void aFunction(string arg1, string arg2)
{
Console.WriteLine(arg1);
Console.WriteLine(arg2);
}
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
A bit of a silly question but i really cant decide, which was is better?
Either:
// Writes a byte array at offset in file
public void WriteByteArray(string file, long offset, byte[] buffer)
but that will force the user to always write the file path, or have it like this:
private string path;
public string File
{
get { return path; }
set { path = value; }
}
// Will do the same thing as the method above just here,
// except it will use the path which was set via "File"
public void WriteByteArray(long offset, byte[] buffer)
There are pros and cons for both. For the first way the pro is, if you want to write the byte array into different files then you can easily do:
WriteByteArray(file_1, 0, new byte[]);
WriteByteArray(file_2, 0, new byte[]);
WriteByteArray(file_3, 0, new byte[]);
but the con is, if you want to just write to one file then constantly typing that path or the string variable containing the path may make the code look a bit messy and unorganized.
The pros for the second way is basically the con for the first way all you do is:
File = "C:\\test.bin";
WriteByteArray(0, new byte[]);
WriteByteArray(0xFF, new byte[]);
WriteByteArray(0x2ACD, new byte[]);
but the con is the pro for the first way aka if you want to write the byte array into different file then you will always have to do File =...
Idk. Which is better? Which way is mostly used?
Since you feel there are pros and cons to both, then just implement both. This seems like a case where there is sufficient demand for either option, and creating one does not preclude the creation of another.
Also, since the first one doesn't require any state variables, make it static so the caller doesn't have to instantiate something just to call it.
Then have your instance method (that uses the File property) call the static method:
class FileWrapper
{
public string File { get; set; }
public static void WriteByteArray(string file, long offset, byte[] buffer)
{
// The real work goes here
}
public void WriteByteArray(long offset, byte[] buffer)
{
// Just call the static method and pass the instance property for the file path
WriteByteArray(this.File, offset, buffer);
}
}
The two interfaces are for entirely different use cases:
The first method, which could be made static, is for writing a buffer to a file at once; there should be no continuations, because the same file could be written in between of your program's writing it, creating a confusion.
The second method is for building a file incrementally from partial buffers. You set the file once, and then write to it until you are done. The class itself should have a Dispose method in order to participate in using statement.
Ultimately, the decision is up to you: pick the interface that matches your intended usage pattern.
Note: Note that since offset could mean an offset in a file or an offset in the buffer, consider renaming the second parameter to fileOffset or filePosition.
The second approach introduces sequential coupling, which is often an anti-pattern (and probably is in this case). It also introduces a global variable (see global variables are bad). So the first method is better (although there is probably a third option that is even better, such as creating an object like FileStream).
But assuming you want to choose from either the first option or second option, pick the first. If you are concerned about code turning out like this....
WriteByteArray(someLongVariableYouDontWantToType, myArray1);
WriteByteArray(someLongVariableYouDontWantToType, myArray2);
WriteByteArray(someLongVariableYouDontWantToType, myArray3);
WriteByteArray(someLongVariableYouDontWantToType, myArray4);
...I suggest you do this (which will also perform better)...
var outputBuffer = new List<byte>();
outputBuffer.AddRange(myArray1);
outputBuffer.AddRange(myArray2);
outputBuffer.AddRange(myArray3);
outputBuffer.AddRange(myArray4);
WriteByteArray(someLongVariableYouDontWantToType, outputBuffer.ToArray());
Or
WriteByteArray
(
someLongVariableYouDontWantToType,
(new[] { myArray1, myArray2, myArray3, myArray4 }).SelectMany(a => a)
);
...both of which concatenate the arrays and write them all in one go. The latter will perform better, but not everyone finds that sort of LINQ code easy to read.
If you did not mean to concatenate, but wish to replace, you should of course just use File.WriteAllBytes().
Since you expect to operate on the same file multiple times, it may be appropriate to use a Builder pattern to solve this problem. Or maybe it isn't. But it's interesting to discuss and could work as a decent answer. Let's have some fun and check it out!
Under the builder pattern, instead of this
WriteByteArray(someLongVariableYouDontWantToType, index1, myArray1);
WriteByteArray(someLongVariableYouDontWantToType, index2, myArray2);
WriteByteArray(someLongVariableYouDontWantToType, index3, myArray3);
WriteByteArray(someLongVariableYouDontWantToType, index4, myArray4);
You'd want your code to look something like this:
myFile
.WriteByteArray(index1, myArray1)
.WriteByteArray(index2, myArray2)
.WriteByteArray(index3, myArray3)
.WriteByteArray(index4, myArray4);
The first step is to create a type that will hold a string that is the file name. We want our own specific type for reasons that will become apparent in a moment. Here's a sample:
public class File
{
public string Path {get; private set; }
public File(string path)
{
Path = path;
}
}
You can use this class like this:
var myFile = new File("c:\temp\MyFileName.txt");
Now that we have a class, we can write an extension method on it:
static public class ExtensionMethods
{
static public File WriteBytes(this File path, int offset, IEnumerable<byte> buffer)
{
OpenFile(path); //Just as an example
SeekIndex(offset); //Just as an example
Write(buffer); //Just as an example
CloseFile(); //Just as an example
return path;
}
}
The key here is the return path line. Because of that, you can chain these together. Now we can do this:
File file = "c:\temp\fileName.txt";
file
.WriteByteArray(index1, myArray1)
.WriteByteArray(index2, myArray2)
.WriteByteArray(index3, myArray3)
.WriteByteArray(index4, myArray4);
Why did we want to use File and not just a string? Well, it would be pretty gauche to write an extension method for string that only works on certain types of strings. Hence the file-specific type.
Now there is one more (small) problem. Each call to WriteByteArray will probably open the file and close it again, which seems inefficient, since we only need to do that once. So in keeping with the builder pattern, we can add another method to signal completion.
static public class ExtensionMethods
{
static public File WriteBytes(this File path, int offset, IEnumerable<byte> buffer)
{
if (!IsFileOpen) OpenFile(path);
SeekIndex(offset);
Write(buffer);
return path;
}
static public void Commit(this File path)
{
CloseFile();
}
}
...which you can use like this:
File file = "c:\temp\fileName.txt";
file
.WriteByteArray(index1, myArray1)
.WriteByteArray(index2, myArray2)
.WriteByteArray(index3, myArray3)
.WriteByteArray(index4, myArray4)
.Commit();
This last part isn't mandatory, but may be a good idea if I/O performance is important to you.
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 have a large file and I am reading each line and depending on what the line contains, I am massaging the line. Here is the code I use when I get to a line that needs to be massaged:
private static void ReviewFile(string fileName, string outFile)
// next initialize StreamReader and read the first line
// depending on the value of that line:
checkFile(out line, ref sw, ref sr); <--- error
Calling:
private void checkFile(out string line, ref StreamWriter sw, ref StreamReader sr)
{
string mVar = line.Trim(); <--- error
sw.WriteLine(mVar);
line = sr.ReadLine();
}
It seems like it should work but I am getting multiple errors. When I call the method, I get "An object reference is required for non-static field" Then within the checkFile method, I get use of unassigned out parameter line. What am I doing wrong? Any help would be graciously appreciated.
In theory, you could simply do the following:
private IEnumerable<string> ReadByLine()
{
string line;
using(StreamReader reader = File.OpenText(FileInformation.FullName))
while((line = reader.ReadLine()) != null)
yield return line;
}
This would allow you to read the file, line by line. Then simply pass the data to another method, to sanitize?
private void Sanitize(IEnumerable<string> document)
{
foreach(var line in document)
{
// Do you check, to sanitize and return or whatever.
}
}
Then you would simply have a two line call in a method:
IEnumerable<string> document = ReadByLine();
Sanitize(document);
This approach would separate the functionality a bit, plus will be easier to follow. Alternative approach to solve your problem. Especially since you approach doesn't seem warranted or viable to enhance the code in anyway.
Based on the code you show, there's absolutely no reason to use ref or out here.
Also, to directly address the issues you ask about, see my comments:
private static void ReviewFile(string fileName, string outFile)
// You're trying to call an instance method from a static method, which doesn't make sense.
// Also, where do you actually declare line, sw, or sr? These are, in fact,
// declared somewhere in this method, right?
checkFile(out line, ref sw, ref sr); <--- error
}
// This is an instance method, NOT a static one
private void checkFile(out string line, ref StreamWriter sw, ref StreamReader sr)
{
// "out" means you intend to initialize "line" in this method before you use it, and you don't.
string mVar = line.Trim(); <--- error
sw.WriteLine(mVar);
// ReadLine doesn't take any arguments
// This should actually be line = sr.ReadLine()
// Also, this should probably go at the beginning of the method
sr.ReadLine(line);
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have an application that writes all sorts of status update and times to the console. I also have an email function that emails to clients. I would like at the end of the application send an email with all lines from the console (same application).
There does not seem to be a function Console.ReadAllLines.
I saw some ideas with GetStdHandle but could get it to work.
Any ideas how I could do this in c# pls?
You can do this by implementing your own TextWriter and Console.SetOut
public class MyWriter : TextWriter
{
private List<string> lines = new List<string>();
private TextWriter original;
public MyWriter(TextWriter original)
{
this.original = original;
}
public override Encoding Encoding
{
get { return Encoding.Default; }
}
public override void WriteLine(string value)
{
lines.Add(value);
original.WriteLine(value);
}
//You need to override other methods also
public string[] GetLines()
{
return lines.ToArray();
}
}
And use it like this
var writer = new MyWriter(Console.Out);
Console.SetOut(writer);
Console.WriteLine("Hello world");
Console.WriteLine("Bye!");
var lines = writer.GetLines();
Reading information back that's already been output to the console is a backwards design. Instead, store the information away in a DB/File/Memory so it can be re-used. continue to display the output as you do. However, when you need to send an email dig the info out of the DB/File/Memory.
It could be done like:
List<string> outputList = new List<string>();
string output = GetOutput();//Run continuously...perhaps in a loop or event trigger..whatever applies
outputList.Add(output);
Console.Writeline(output);
//when ready
SendEmail(outputList);
You could write a wrapper class to take care of it easily.
public class ConsoleWriter()
{
public static List<string> AllLines = new List<string>();
public static WriteConsole(string text)
{
AllLines.Add(text);
Console.Write(text);
}
}
Then read AllLines when you want to send the mail.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
I'm new to C#, so this may be a basic question. What I need to do is put an array such as the one below in a class library and then make a call to it. So I'd want the appropriate picture to appear via the class and this array. I know there's a much simpler way to make certain pictures appear, but this is a requirement for the project. It's an asp.NET website in C#.
string[] PictureArray;
PictureArray = new string[3];
PictureArray[0] = "~/pics/grl.jpg";
PictureArray[1] = "~/pics/pop.jpg";
PictureArray[2] = "~/pics/str.jpg";
PictureArray[3] = "~/pics/unk.jpg";
EDIT (also in comment):
I'm trying to get the picture from the array to show up in an image box upon a button click like this:
protected void Button1_Click(object sender, EventArgs e) {
Class1 name = new Class1();
this.Image1.ImageUrl = name.GetPic();
}
Obviously just the name.GetPic() isn't going to do anything, it's throwing an error actually.
EDIT2: Sorry for the confusion, I just realized I can edit and comment. I've got the array in the class properly setup, now I need to access it (read above edit).
Answered
string[] pictures = work.GetPictures();
Image1.ImageUrl = pictures[0];
is all that I needed to see, thanks Zyphrax
ok, it seems that you've put some effort into this.
I think you're looking for something like the sample below.
I've added comments to help you understand what's going on.
One of the classes in your class library:
// Define a class called HomeWork, make it accessible to other
// classes in other namespaces
public class HomeWork {
// Define a method called GetPictures, no incoming arguments,
// returns a string[]
public string[] GetPictures() {
// Create a new instance of a string array
string[] pictures = new string[4];
// Fill the string array with a couple of strings
pictures[0] = "~/pics/grl.jpg";
pictures[1] = "~/pics/pop.jpg";
pictures[2] = "~/pics/str.jpg";
pictures[3] = "~/pics/unk.jpg";
// Return the string array
return pictures;
}
}
How to call the method on that class:
// Create a new instance of the HomeWork class
HomeWork work = new HomeWork();
// Call the GetPictures method
work.GetPictures();
Please ask your teacher to explain it into more detail.
We can't teach you years of programming experience in one SO question :)
EDIT: In response to your second question
Option 1: use the array that was returned by GetPictures:
HomeWork work = new HomeWork();
string[] pictures = work.GetPictures();
Image1.ImageUrl = pictures[0];
Image2.ImageUrl = pictures[1];
Image3.ImageUrl = pictures[2];
// etc..
Option 2: create an overload for GetPictures that accepts an index
public string[] GetPictures() {
// This method remains unchanged
}
public string[] GetPictures(int index) {
// Get the string array from GetPictures
string[] pictures = GetPictures();
// Return a specific index
return pictures[index];
// As you can see, this method might be
// dangerous to use, because someone could
// ask for an invalid index causing an
// IndexOutOfRangeException
}
HomeWork work = new HomeWork();
Image1.ImageUrl = work.GetPictures(0);
Image2.ImageUrl = work.GetPictures(1);
Image3.ImageUrl = work.GetPictures(2);
The samples above are to illustrate how C# works.
It would be inefficient to use it this way in a business application.
I can only add to this via an answer.
public class Class1
{
public string ArrayMethod (string ArrayMethod)
{
string[] PictureArray;
PictureArray = new string[3];
PictureArray[0] = "~/pics/grl.jpg";
PictureArray[1] = "~/pics/pop.jpg";
PictureArray[2] = "~/pics/str.jpg";
PictureArray[3] = "~/pics/unk.jpg";
}
}
This is how I've tried putting the array in a class. When it builds I get the error "not all code paths return a value". For a start you could help me get that working. And yes this is for school, and as far as I can tell this is how you learn programming if it's something the teacher didn't cover. I'm not asking you to write my code, I'm just stuck with it.
I have my Windows Application that accepts args and I use this in order to set up the Window behaviour
problem is that I need to pass text in some of this arguments but my application is looking at it as multiple args, so, this:
"http://www.google.com/" contact 450 300 false "Contact Info" true "Stay Visible" true
has actually 11 arguments instead of the 9 that I am expecting.
What is the trick to get "contact info" and "stay visible" to be passed as only one argument?
Are you running it directly from the command line? If so, I'd expect that to work just fine. (I assume you're using the parameters from the Main method, by the way?)
For instance, here's a small test app:
using System;
class Test
{
static void Main(string[] args)
{
foreach (string arg in args)
{
Console.WriteLine(arg);
}
}
}
Execution:
>test.exe first "second arg" third
first
second arg
third
This is a console app, but there's no difference between that and WinForms in terms of what gets passed to the Main method.
MSDN says, that it should work the way you mentioned.
class CommandLine
{
static void Main(string[] args)
{
// The Length property provides the number of array elements
System.Console.WriteLine("parameter count = {0}", args.Length);
for (int i = 0; i < args.Length; i++)
{
System.Console.WriteLine("Arg[{0}] = [{1}]", i, args[i]);
}
}
}
How are you executing your application?
If you execute it from another application you might have forgotten to format the argument string properly:
String arguments = "First \"Sec ond\" Third Fourth \"Fi fth\""
would have five arguments whereas
String arguments = "First Sec ond Third Fourth Fi fth"
would have seven.
If the arguments are in the shortcut target property then the same applies:
"C:\My Path\MyApplication.exe" "Argument 1" Argument2 Argument3 "Argument 4"
instead of
"C:\My Path\MyApplication.exe" Argument 1 Argument2 Argument3 Argument 4